Java Debugging & Profiling Techniques

Slides:



Advertisements
Similar presentations
Chapter 17 Failures and exceptions. This chapter discusses n Failure. n The meaning of system failure. n Causes of failure. n Handling failure. n Exception.
Advertisements

1 Exceptions: An OO Way for Handling Errors Rajkumar Buyya Grid Computing and Distributed Systems (GRIDS) Laboratory Dept. of Computer Science and Software.
Exceptions CSE301 University of Sunderland Harry Erwin, PhD.
11-Jun-14 The assert statement. 2 About the assert statement The purpose of the assert statement is to give you a way to catch program errors early The.
COM vs. CORBA.
Exceptions Chapter Throwing and Catching Exceptions When a program runs into a problem that it cannot handle, it throws an exception. Exceptions.
Yoshi
Exception Handling. Background In a perfect world, users would never enter data in the wrong form, files they choose to open would always exist, and code.
Lecture 23 Input and output with files –(Sections 2.13, 8.7, 8.8) Exceptions and exception handling –(Chapter 17)
Class Hierarchy (Inheritance)
Exceptions and Exception Handling Carl Alphonce CSE116 March 9, 2007.
Exception Handling1. 2 Exceptions  Definition  Exception types  Exception Hierarchy  Catching exceptions  Throwing exceptions  Defining exceptions.
MIT-AITI Lecture 14: Exceptions Handling Errors with Exceptions Kenya 2005.
EXCEPTIONS. What’s an exception?? Change the flow of control when something important happens ideally - we catch errors at compile time doesn’t happen.
Exception Handling Chapter 12.  Errors- the various bugs, blunders, typos and other problems that stop a program from running successfully  Natural.
Slides prepared by Rose Williams, Binghamton University ICS201 Exception Handling University of Hail College of Computer Science and Engineering Department.
11-Jun-15 Exceptions. 2 Errors and Exceptions An error is a bug in your program dividing by zero going outside the bounds of an array trying to use a.
1 From Yesterday private = accessible only to the class that declares it public = accessible to any class at all protected = accessible to the class and.
Exceptions Three categories of errors: Syntax errors Runtime errors Logic errors Syntax errors: rules of the language have not been followed. Runtime error:
16-Jun-15 Exceptions. Errors and Exceptions An error is a bug in your program dividing by zero going outside the bounds of an array trying to use a null.
Exceptions in Java Fawzi Emad Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
Exceptions. Errors and Exceptions An error is a bug in your program –dividing by zero –going outside the bounds of an array –trying to use a null reference.
© 2006 Pearson Addison-Wesley. All rights reserved4-1 Chapter 4 Data Abstraction: The Walls.
© 2006 Pearson Addison-Wesley. All rights reserved4-1 Chapter 4 Data Abstraction: The Walls.
Exceptions. Many problems in code are handled when the code is compiled, but not all Some are impossible to catch before the program is run  Must run.
1 Web Based Programming Section 6 James King 12 August 2003.
1 Exception Handling Introduction to Exception Handling Exception Handling in PLs –Ada –C++ –Java Sebesta Chapter 14.
June 14, 2001Exception Handling in Java1 Richard S. Huntrods June 14, 2001 University of Calgary.
Liang, Introduction to Java Programming, Seventh Edition, (c) 2009 Pearson Education, Inc. All rights reserved Chapter 18 Exception Handling.
Object Oriented Programming
Exception Handling in Java Exception Handling Introduction: After completing this chapter, you will be able to comprehend the nature and kinds.
Slides Credit Umair Javed LUMS Web Application Development.
The Java Programming Language
Debugging in Java. Common Bugs Compilation or syntactical errors are the first that you will encounter and the easiest to debug They are usually the result.
Java Threads. What is a Thread? A thread can be loosely defined as a separate stream of execution that takes place simultaneously with and independently.
Introduction to Exception Handling and Defensive Programming.
Spring/2002 Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads 1 RMI.
Exception Handling Unit-6. Introduction An exception is a problem that arises during the execution of a program. An exception can occur for many different.
BIO Java 1 Exception Handling Aborting program not always a good idea – can’t lose messages – E-commerce: must ensure correct handling of private.
Java Basics Opening Discussion zWhat did we talk about last class? zWhat are the basic constructs in the programming languages you are familiar.
Exceptions and Assertions Chapter 15 – CSCI 1302.
Exception Handling in Java Topics: Introduction Errors and Error handling Exceptions Types of Exceptions Coding Exceptions Summary.
Exceptions in Java. What is an exception? An exception is an error condition that changes the normal flow of control in a program Exceptions in Java separates.
Copyright © Curt Hill Error Handling in Java Throwing and catching exceptions.
Programming & Debugging. Key Programming Issues Modularity Modifiability Ease of Use Fail-safe programming Style Debugging.
1 Exceptions. 2 Syntax Errors, Runtime Errors, and Logic Errors syntax errors, runtime errors, and logic errors You learned that there are three categories.
© 2006 Pearson Addison-Wesley. All rights reserved 1-1 Chapter 1 Review of Java Fundamentals.
Exceptions Lecture 11 COMP 401, Fall /25/2014.
Lecture10 Exception Handling Jaeki Song. Introduction Categories of errors –Compilation error The rules of language have not been followed –Runtime error.
And other languages…. must remember to check return value OR, must pass label/exception handler to every function Caller Function return status Caller.
Throw, Throws & Try-Catch Statements Explanations and Pictures from: Reference:
ECE122 L23: Exceptions December 6, 2007 ECE 122 Engineering Problem Solving with Java Lecture 24 Exceptions.
Winter 2006CISC121 - Prof. McLeod1 Last Time Reviewed class structure: –attributes –methods –(inner classes) Looked at the effects of the modifiers: –public.
Garbage Collection It Is A Way To Destroy The Unused Objects. To do so, we were using free() function in C language and delete() in C++. But, in java it.
Object Throwable ErrorException RuntimeException.
Java Thread Programming
Object Oriented Programming in
Exception Handling and Event Handling
Java Programming Language
Fall 2017 CISC124 9/21/2018 CISC124 First onQ quiz this week – write in lab. More details in last Wednesday’s lecture. Repeated: The quiz availability.
Java Programming Language
Web Design & Development Lecture 7
(Computer fundamental Lab)
Exceptions 25-Apr-19.
Errors and Exceptions Error Errors are the wrongs that can make a program to go wrong. An error may produce an incorrect output or may terminate the execution.
Exceptions 22-Apr-19.
Exceptions 10-May-19.
Exceptions 5-Jul-19.
Exception Handling.
Java Virtual Machine Profiling. Agenda Introduction JVM overview Performance concepts Monitoring Profiling VisualVM demo Tuning Conclusions.
Presentation transcript:

Java Debugging & Profiling Techniques Ethan Henry egh@klg.com KL Group http://www.klgroup.com

Overview This session will touch on three major topics: Debugging and Profiling plus Memory Leaks in Java

Debugging What’s debugging? If you don’t already know… Debugging is the process of finding errors in your software, regardless of what kind of errors they are

Types of Errors Program errors can be lumped into one of three broad categories: syntactic errors static errors dynamic errors Syntactic errors are the easiest to find, dynamic errors are the most difficult

Syntactic Errors A syntactic error is one in which the program is ill-formed by the standard of the programming language e.g. a keyword is misspelled Syntactic errors are trivial to detect and correct the compiler does the detection for you which is one reason compiled languages are so popular

Static Errors Static errors are ones in which the program is syntactically correct but semantically incorrect For example, substituting a “>” for a “<” Static errors can be very difficult to detect but are usually quite obvious Java’s exception mechanism helps deal with these types of errors

Dynamic Errors The dynamic error is the most insidious kind of errors Dynamic errors occur in code which is both semantically and syntactically correct but where implicit assumptions have been violated The prevention of dynamic errors is a major focus of software engineering

Dynamic Errors An example of a dynamic error: the most dramatic example I could find The Ariane 5 crash on June 4, 1996 was due to a reuse error reuse of an inertial reference system software component caused a 64-bit integer to be incorrectly converted into a 16-bit unsigned integer, causing an exception that went uncaught and crashed the guidance system http://www.eiffel.com/doc/manuals/technology/contract/ariane/index.html

Debugging Techniques Debugging is an art as old as programming is, so there are a lot of approaches to it For Java, we can divide debugging techniques into two categories: “Classic” Java-specific

Classic Debugging Techniques print statements assert

Jurassic Debugging println statements System.out.println connected to the standard output stream System.err.println connected to the standard error stream both are instances of java.io.PrintStream helps with static & dynamic errors difficult to deal with in general

toString() The one very useful thing about using println to debug is that every object has a toString() method inherited from Java.lang.Object This means that you can always do things like this: Frame f = new Frame(“Main App”); System.out.println(“The frame info is “+f);

toString() By default, toString() just prints out an object identifier, so you should override it in your own classes Tip: The first thing you should do in a toString method is create a StringBuffer to hold the data you’re printing

Using println How can you make debugging statements easier to deal with? Conditional code via if via a pre-processor a debugging class

Using println If use an expression that’s constant at compile time, if statements act like conditional code and will be evaluated at compile time static final boolean DEBUG = true; // or false … if(DEBUG) { System.out.println(“Some message”); }

Using println Another option is to use an actual pre-processor, like in C/C++ cpp, perl, m4, tcl - any general scripting language should work This is more complex, but is marginal extra work in a large project Advantage over using if: you can completely strip out the debugging code if you want

Using println Another technique is to use a class that logs errors typically a singleton For example:

import java.io.*; public final class Log { private static Log log; private PrintStream stream; private boolean printing; private Log() { stream = System.out; printing = true; } static { log = new Log(); public static Log getLog() { return log;

public void setPrinting(boolean b) { } public void setStream(OutputStream os) { if(os instanceof PrintStream) stream = (PrintStream)os; else stream = new PrintStream(os); public void println(String msg) { if(printing) stream.println(msg); public void print(String msg) { stream.print(msg);

Assert Assert is a classic C & C++ programming construct Assert statements are used to verify various conditions in program code Very useful for detecting dynamic errors For example: public int doThing(int x) { Assert.assert(x > 0); // do some things... }

Assert While the C assert stops the program, a Java assert would be better off doing something less intrusive, like throwing a RuntimeException There is an example of a full assert package (JContracts) at: http://www.halcyon.com/nickx/JContracts/ There’s a JSR on the subject as well: http://java.sun.com/aboutJava/communityprocess/jsr/jsr_041_asrt.html

A sample assert class public final class Assert { // change to false if you want to disable assertions private final static boolean ENFORCE = true; public static void assert(boolean b) { if(ENFORCE && (b == false)) throw new RuntimeException("assertion violated"); }

Java-Specific Techniques Exception Handling Reading Exception Messages Thread Dumps

Exception Handling An exception is “thrown” when some unexpected condition occurs at runtime Only instances of java.lang.Throwable (or a subclass) can be thrown by the throw statement Throwable has two subclasses: java.lang.Error java.lang.Exception

Errors Error objects are thrown by the virtual machine or Java library to indicate a serious problem Most applications shouldn’t try to catch or throw an Error object The predefined errors are:

Errors java.awt.AWTError java.lang.LinkageError java.lang.ClassCircularityError java.lang.ClassFormatError java.lang.ExceptionInInitializerError java.lang.IncompatibleClassChangeError java.lang.AbstractMethodError java.lang.IllegalAccessError java.lang.InstantiationError java.lang.NoSuchFieldError java.lang.NoSuchMethodError java.lang.NoClassDefFoundError java.lang.UnsatisfiedLinkError java.lang.VerifyError java.lang.ThreadDeath java.lang.VirtualMachineError java.lang.InternalError java.lang.OutOfMemoryError java.lang.StackOverflowError java.lang.UnknownError

Exceptions An exception indicates some sort of problem that a typical application might want to deal with There are two types of exceptions: checked exceptions unchecked exceptions

Checked Exceptions Direct subclasses of java.lang.Exception represent exceptions that the developer must deal with These exceptions can only be thrown if declared in the throws clause of the method Any code calling a method that throws a regular exception must catch it and deal with it

Checked Exceptions Some examples of checked exceptions are: java.lang.ClassNotFoundException thrown by Class.forName() java.io.IOException thrown by many I/O operations java.lang.IllegalAccessException thrown by Class.newInstance() java.lang.InterruptedException thrown by sleep and wait

Unchecked Exceptions Unchecked exceptions need not be declared in the throws clause of a method and do not need to be caught These are exceptions that are too frequent to check for every time Unchecked exceptions are derived from java.lang.RuntimeException instead of java.lang.Exception RuntimeException is derived from Exception though

Unchecked Exceptions Some example of unchecked exceptions: java.lang.ArithmeticException java.lang.ClassCastException java.lang.IllegalArgumentException java.lang.NumberFormatException java.lang.ArrayIndexOutOfBoundsException java.lang.StringIndexOutOfBoundsException java.lang.NegativeArraySizeException java.lang.NullPointerException

Handling Exceptions Exceptions are dealt with via the throw, try, catch and finally keywords The code that encounters a problem creates an exception by instantiating some exception object and throwing it throw new SomeBadException(“some message”);

Handling Exceptions The exception then unwinds the stack of the thread it was thrown in, looking for a try block If there is a catch associated with the try block that matches the type of the exception, the catch block is executed After the catch block executes (or if no exception was thrown) the finally block associated with the try block is executed

Handling Exceptions If no handler is found, the current thread’s ThreadGroup’s uncaughtException(Thread,Throwable) method is called if there is a parent ThreadGroup, pass it the exception otherwise print the exception stack trace to System.err

Handling Exceptions import java.io.IOException; public class Exception { public static void main(String args[]) { try { foo(args[0]); System.out.println("whew"); } catch(IOException e) { System.out.println("doh!"); finally { System.out.println("finally..."); System.out.println("done!");

Handling Exceptions public static void foo(String s) throws IOException { if(s.equals("checked")) { throw new IOException("Checked"); } else if(s.equals("unchecked")) { throw new RuntimeException("Unchecked"); System.out.println("No exception");

Reading Exception Messages A typical exception stack trace looks something like this: from a modified version of the ‘Fractal’ example that comes with the JDK java.lang.NullPointerException at ContextLSystem.<init>(CLSFractal.java:319) at CLSFractal.init(CLSFractal.java:66) at sun.applet.AppletPanel.run(AppletPanel.java:287) at java.lang.Thread.run(Thread.java:474)

Reading Exception Messages Information shown: the type of exception java.lang.NullPointerException the class & method in which the exception was thrown at ContextLSystem.<init>(CLSFractal.java:319) the full stack trace for the thread executing the code at that point at CLSFractal.init(CLSFractal.java:66) at sun.applet.AppletPanel.run(AppletPanel.java:287) at java.lang.Thread.run(Thread.java:474) Note that line numbers are not shown if a JIT is being used

Reading Exception Messages There are two special methods that aren’t identified by their human-readable names: <init> a constructor <clinit> the static “class constructor” code block

The “Magic Thread Dump Key” Windows: Ctrl-Break Solaris: Ctrl-\ or kill -QUIT [pid] A sample thread dump How to read a thread dump Diagnosing deadlock

A Sample Thread Dump From a sample application: Full thread dump Classic VM (JDK-1.2-V, native threads): "Thread-0" (TID:0x1915a28, sys_thread_t:0x8ebd60, state:CW, native ID:0x113) prio=5 "AWT-Windows" (TID:0x1916ce0, sys_thread_t:0x8a6410, state:R, native ID:0x10a) prio=5 at sun.awt.windows.WToolkit.eventLoop(Native Method) at sun.awt.windows.WToolkit.run(WToolkit.java:134) at java.lang.Thread.run(Thread.java:479) "SunToolkit.PostEventQueue-0" (TID:0x1916e10, sys_thread_t:0x8a5b70, state:CW, native ID:0x103) prio=5 at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Compiled Code) at sun.awt.PostEventQueue.run(SunToolkit.java:363) "AWT-EventQueue-0" (TID:0x1916de0, sys_thread_t:0x8a3680, state:CW, native ID:0x10d) prio=6 at java.awt.EventQueue.getNextEvent(EventQueue.java:179) at java.awt.EventDispatchThread.run(EventDispatchThread.java:67) "Finalizer" (TID:0x18f9320, sys_thread_t:0x8209d0, state:CW, native ID:0x116) prio=8 at java.lang.ref.ReferenceQueue.remove(Compiled Code) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:174)

A Sample Thread Dump "Reference Handler" (TID:0x18f93b0, sys_thread_t:0x81fdc0, state:CW, native ID:0x10f) prio=10 at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Compiled Code) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:114) "Signal dispatcher" (TID:0x18f93e0, sys_thread_t:0x81f560, state:R, native ID:0x117) prio=5 Monitor Cache Dump: sun.awt.PostEventQueue@1916E10/1957BC0: <unowned> Waiting to be notified: "SunToolkit.PostEventQueue-0" (0x8a5b70) java.awt.EventQueue@1916D90/19579B8: <unowned> "AWT-EventQueue-0" (0x8a3680) java.lang.ref.ReferenceQueue$Lock@18F9338/192ED78: <unowned> "Finalizer" (0x8209d0) java.lang.ref.Reference$Lock@18F93C0/192E8A8: <unowned> "Reference Handler" (0x81fdc0)

A Sample Thread Dump Registered Monitor Dump: Invoker change lock: <unowned> utf8 hash table: <unowned> JNI pinning lock: <unowned> JNI global reference lock: <unowned> BinClass lock: <unowned> Class linking lock: <unowned> System class loader lock: <unowned> Code rewrite lock: <unowned> Heap lock: <unowned> Monitor cache lock: owner "Signal dispatcher" (0x81f560) 1 entry Thread queue lock: owner "Signal dispatcher" (0x81f560) 1 entry Waiting to be notified: "Thread-0" (0x8ebd60) Monitor registry: owner "Signal dispatcher" (0x81f560) 1 entry

How to Read a Thread Dump The thread dump contains the following information: a listing of all the threads running in the VM including a full stack dump if available plus the native thread id, priority and current thread state a list of all monitors that have been created including the current owner and the number of threads waiting for that monitor to be released a list of all “special” monitors these are used by the VM internally

Thread States Each thread has a state associated with it: R Running or runnable thread S Suspended thread CW Thread waiting on a condition variable MW Thread waiting on a monitor lock MS Thread suspended waiting on a monitor lock You should never see a thread in the ‘MS’ state if you do, there’s a good chance it’s a VM bug

More on Thread Dumps The JDC has a very nice, detailed description of what each element in the thread dump is: http://developer.java.sun.com/developer/technicalArticles/Programming/Stacktrace This includes details on what each of the internal monitors are for and more It’s for JDK 1.1, but should be helpful for JDK 1.2 as well

Other Magic Keys Related to the “Magic Thread Dump” key is the “Magic AWT Dump” key Ctrl+Shift+F1 the code for this is hidden away inside java.awt.Window of all places Magic Netscape Console Keys hit ? in the Navigator Java console to get the list of commands

Interactive Debuggers Free: jdb JBuilder Foundation (IDE) http://www.borland.com/jbuilder NetBeans Developer/Forte for Java (IDE) http://www.netbeans.com Commercial: Metamata Debug http://www.metamata.com Karmira BugSeeker http://www.karmira.com

JDK 1.0/1.1 Debugging API The Java VMs in JDK 1.0 and JDK 1.1 support a basic remote debugging API A remote agent is built into the Java VM which can be accessed over a socket via the RemoteDebugger class Most of this API has never been formally published

Instance of RemoteDebugger JDK 1.0/1.1 Debugging API The basic debugger architecture: h Java Interpreter Java VM Agent Request Reply Instance of RemoteDebugger Java Debugging Client

JDK 1.0/1.1 Debugging API To use the debugging agent, start the JVM with the -debug command line option this may require the use of java_g On the debug client side, create an instance of the RemoteDebugger class which can be used to: list all classes in the target JVM obtain a specific RemoteClass monitor memory usage and initiate GC

JDK 1.0/1.1 Debugging API The RemoteClass class can be used to: get all the fields & methods in the class set breakpoints in methods All of these classes are in the sun.tools.debug package source for this package is not included with the JDK although it is included with the VM source

JDK 1.0/1.1 Debugging API The classes in sun.tools.debug are: RemoteValue RemoteBoolean RemoteByte RemoteChar RemoteDouble RemoteFloat RemoteInt RemoteLong RemoteShort RemoteObject RemoteArray RemoteClass RemoteString RemoteThread RemoteThreadGroup RemoteField RemoteStackVariable RemoteDebugger DebuggerCallback

JDK 1.2 Debugging API JDK 1.2 has a new, improved debugging API that is fully documented http://java.sun.com/products/jpda/ The JPDA API has been broken down into three isolated parts: JVMDI: Java Virtual Machine Debug Interface. A low-level native interface. Defines the services a VM must provide for debugging.

JDK 1.2 Debugging API JDWP: Java Debug Wire Protocol Defines the format of information and requests transferred between the debugging process and the debugger front-end The transport mechanism is unspecified could be a socket, shared memory, etc JDI: Java Debug Interface A high-level 100% Pure Java interface, including support for remote debugging For use on the client/debugger side

communication channel JDK 1.2 Debugging API VM back-end JVMDI debuggee communication channel JDWP front-end JDI debugger UI

Profiling What is Profiling? What Profiling Tells You What Profiling Is Not Manual Profiling Profiling Techniques Overview Insertion Sampling Instrumented VM

What is Profiling? Profiling is measuring an application, specifically: where is the time being spent? This is “classical” profiling which method takes the most time? which method is called the most? how is memory being used? what kind of objects are being created? this in especially applicable in OO, GC’ed environments

What Profiling Tells You Basic information: How much time is spent in each method? (“flat” profiling) How many objects of each type are allocated?

What Profiling Tells You Beyond the basics: Program flow (“hierarchical” profiling) do calls to method A cause method B to take too much time? Per-line information which line(s) in a given method are the most expensive? Which methods created which objects? Visualization aspects Is it easy to use the profiler to get to the information you’re interested in?

What Profiling Is Not Profiling is measuring performance statistics on your particular application regardless of the underlying platform Benchmarking is measuring the performance of a particular platform not a specific application Optimization is an automatic technique that applies generic enhancements to speed up code regardless of the application or platform

Optimization Even though optimization isn’t always enough, it’s a good place to start Java is designed to be optimized by the JVM, not by the compiler even though there are optimizing compilers JIT compilers help Sun’s next-generation JVM, HotSpot, offers: generational garbage collection improved, profiling native compiler

Manual Profiling You don’t absolutely need to have a profiling tool to profile your code… you could build your own profiling tool see Dr. Dobb’s Journal, March 1998 Or Dr. Dobbs, Sept. 1999 use very simple code-insertion techniques System.out.println(System.getCurrentTimeMillis());

Profiling Techniques Overview Commercial profilers use one of three techniques for profiling programs: insertion sampling instrumented virtual machine Why is it important to understand how a profiler works? each different technique has its own pros & cons different profilers may give different results

Insertion Multiple flavours: Source code insertion profiling code goes in with the source easy to do Object code insertion profiling code goes into the .o (C++) or .class (Java) files can be done statically or dynamically hard to do modified class loader

Insertion Pros & Cons Insertion Pros: Insertion Cons: can be used across a variety of platforms accurate (in some ways) can’t easily do memory profiling Insertion Cons: requires recompilation or relinking of the app profiling code may affect performance difficult to calculate exact impact

Sampling In sampling, the processor or VM is monitored and at regular intervals an interrupt executes and saves a “snapshot” of the processor state This data is then compared with the program’s layout in memory to get an idea of where the program was at each sample

Sampling Pros & Cons Sampling Pros: Sampling Cons: no modification of app is necessary Sampling Cons: a definite time/accuracy trade-off a high sample rate is accurate, but takes a lot of time more…

Sampling Pros & Cons Sampling Cons: very small methods will almost always be missed if a small method is called frequently and you have are unlucky, small but expensive methods may never show up sampling cannot easily monitor memory usage

Instrumented VM Another way to collect information is to instrument the Java VM Using this technique each and every VM instruction can be monitored highly accurate

Instrumented VM Pros&Cons The most accurate technique Can monitor memory usage data as well as time data Can easily be extended to allow remote profiling Cons: The instrumented VM is platform-specific

Instrumented VMs Java 2 (JDK 1.2 and higher) Microsoft JVM information can be accessed through JVMPI the Java Virtual Machine Profiling Interface http://java.sun.com/products/jdk/1.3/docs/guide/jvmpi/ Microsoft JVM uses a COM-based interface to provide profiling information JProbe Profiler

Common Bottlenecks Although profiling can yield some surprises, often the bottlenecks are fairly obvious once the profiler points them out excessive heap expansion not using System.arraycopy() using the “+” operator with String objects using unbuffered I/O streams excessive memory allocations excessive calls to slow library methods

Memory Leaks Java doesn’t have “memory leaks” like a C or C++ program, but… Some Java programs exhibit classic “memory leak” behavior: their memory usage grows, unbounded, over time Memory leaks usually also lead to performance problems once the process starts getting swapped out

What is a Memory Leak? Allocated Reachable Live exists on the heap a path exists from some root to it Live program may use it along some future execution path

What is a memory leak? Memory leak in C/C++ allocated reachable Memory leak in Java live

Loiterers We like to call these objects “loiterers” because: they’re not really leaks - you can probably still release the memory somehow we don’t want to confuse Java-heap problems with native-heap problems caused by native code, which could be real memory leaks

Lapsed Listener Object added to collection, not removed e.g. event listener, observer collection size can grow without bound iteration over “dead” objects degrades performance Most frequent loitering pattern Swing and AWT have had many occurs easily in any large framework C++: small loiterer or dangling pointer

Lingerer Reference used transiently by long-term object Reference always reset on next use e.g. associations with menu items e.g. global action or service Not a problem in C++ benign dangling reference

Laggard Object changes state, some references still refer to previous state also a hard-to-find bug Common culprits changing life-cycle of class (e.g. into a singleton) constructor sets up state caches expensive-to-determine object state changes, cache not maintained C++: dangling pointer

Limbo Reference pinned by long-running thread Common culprits references on stack GC doesn’t do local liveness analysis Common culprits thread stall expensive setup calls long-running analysis C++: placement of destructors

Loiterers For more information on causes of loiterers and how to prevent them, see the article: ‘How Do You Plug Java Memory Leaks?’ in Dr.Dobb’s, Feb. 2000 also at: http://www.ddj.com/articles/2000/0002/0002l

Memory Leaks So, how can you identify & track down memory leaks? This is almost impossible to do without a memory analysis tool Some tools: HAT (defunct) http://developer.javasoft.com/developer/earlyAccess/hat/ JProbe OptimizeIt

Questions?

Fin Check out JProbe at: http://www.klgroup.com/jprobe Contact me at: egh@klgroup.com