ProcedureDetecting Memory Leaks

 

A typical problem with Java programs is memory leakage, which causes the memory usage of the heap to grow continuously. This may lead to OutOfMemoryErrors.

Procedure

The procedure is best described with an example. The following example program demonstrates an out-of-memory situation.

Syntax Syntax

  1. public class OOM {
    
        class Leak {
            int dummy;
        }
        
        public static void main(String[] args) {
            LinkedList<Leak[]> list = new LinkedList<Leak[]>();
            
            while (true) {
                list.add(new Leak[1024]);
            }
        }
    }
    
End of the code.

Once again, the SAP Management Console is a good starting point if you suspect a leaking program. The following graphic shows the AS Java Heap memory view in the MMC. If there is a memory leak, the heap is continuously growing.

Heap Memory Information in the Management Console

This graphic is explained in the accompanying text.

The node AS Java GC History also shows the number of GCs and number of full GCs that have already been run. You also get some statistical information for the GCs that have taken place. This is useful to determine the memory usage trend of the system (is the heap growing slowly/quickly , in which time-frame and so on).

This graphic is explained in the accompanying text.

Another interesting dump is the class statistic dump which is contained in the thread dump. It summarizes the objects found in the generations of the Java heap. It displays the number and the cumulated size of the objects in specific generations. This allows you to identify the classes whose objects consume the most space. Additionally it can be used to check which classes and class loaders are still alive, to track down memory leaks in the permanent generation.

Example Example

The information contained in the thread dump in our example looks like:

J num   #instances     #bytes   class name

J  ---------------------------------------------------------------------

J    1       10257   42176784   OOM$Leak[]

J    2       10258     246192   java.util.LinkedList$Entry

J    3         310      57456   char[]

J    4          21      44816   byte[]

J    5         470      12128   java.lang.String[]

...

J Total      24007   43162588

End of the example.

In our example, the class OOM$Leak consumes 99 % of the Java heap. In order to examine why these objects are still alive, a heap dump is needed. This heap dump can be analyzed further with tools like the SAP Memory Analyzer or jhat to find the root cause of the memory leak.

In this example, we did a lot of manual steps to analyze the memory leak. To analyze a memory leak, a typical set of information (a class statistic, a heap dump, …) is helpful in all cases. The SAP JVM can store a lot of this needed data when an OutOfMemoryError occurs and allows a post mortem analysis.

When the VM options

  • -XX:+DumpGCHistoryOnOutOfMemory

  • -XX:+DumpDetailedClassStatisticOnOutOfMemory

  • -XX:+HeapDumpOnOutOfMemoryError

are set, a GC history, a class statistic, and a heap dump are created when an OutOfMemory error occurs. These options are not set in the default configuration, as a large amount of data is created. You should set these options when you experience many out-of-memory situations and want to track them down.