ProcedureAnalyzing Out-of-Memory Situations

 

A common problem that many developers find is that of applications that terminate with java.lang.OutOfMemoryError. A related problem arises with applications that terminate because the virtual memory on the operating system is exhausted (or close to exhaustion).

Procedure

First, you have to detect the cause of the out-of-memory situation.

What does OutOfMemoryError mean?

The java.lang.OutOfMemoryError error is thrown when there is insufficient space to allocate an object in the Java heap (or a particular area of the heap). That is, the garbage collection cannot make any further space available for a new object and the heap cannot be expanded further. An OutOfMemoryError does not imply a memory leak – the issue can be as simple as a configuration issue where the specified heap size (or the default size if not specified) is insufficient for the application.

A java.lang.OutOfMemoryError error can also be thrown by native library code when a native allocation cannot be satisfied. When an OutOfMemoryError is thrown it is not always obvious (at least initially) if the Java heap is exhausted or there is native heap exhaustion (low swap space for example).

The first step in the diagnosis of an OutOfMemoryError is to find out what the error means. Does it mean that the Java heap is full or does it mean that the native heap is full? Here we list some of the possible error messages and explain what they mean:

  • Exception in thread “main” java.lang.OutOfMemoryError: Java heap space

    This indicates that an object could not be allocated in the Java heap. This may be a configuration issue; for example the -Xmx option may have been used to specify a maximum heap size that is not sufficient for the application.

    For a long-lived application it may be an indication that the application (or libraries used by that application) is unintentionally holding references to objects, which prevents them from being garbage collected.

    Another source of an OutOfMemoryError can be applications that make excessive use of finalizers. If a class has a finalize method, then objects of that type do not have their space reclaimed at garbage collection time. Instead, after garbage collection, the objects are queued for finalization, which occurs sometime later. In the SAP JVM implementation finalizers are executed by a daemon thread that services the finalization queue. If the finalizer thread cannot keep up with the finalization queue, it is possible that the Java heap will fill up and an OutOfMemoryError will be thrown.

  • Exception in thread “main” java.lang.OutOfMemoryError: PermGen space

    This indicates that the permanent generation is full, which is the area of the heap where class and method objects are stored. If an application loads a huge number of classes then the permanent generation may need to be increased using the -XX:MaxPermSize VM parameter.

    The permanent generation is also used when java.lang.String objects are interned. If an application interns a huge number of strings it also may require the permanent generation to be increased.

  • Exception in thread “main” java.lang.OutOfMemoryError: Requested array size exceeds VM limit

    This indicates that the application attempted to allocate an array that is larger than the heap size. This is either a configuration problem (heap size too small) or a bug that results in an application attempting to create a huge array.

  • Exception in thread “main” java.lang.OutOfMemoryError: request <size> bytes for <reason>. Out of swap space?

    This exception is reported by the SAP JVM code when an allocation from the native heap failed and the native heap is close to exhaustion. In some cases the reason will be shown but in most cases the reason will be the name of a source module reporting the allocation failure. An OutOfMemoryError like this indicates a necessary diagnosis of the operating system. Most probably the configured swap space is too small. If that native libraries are used with the VM, a native memory leak could also be the source of the problem.

Is a Restart Necessary?

In the past, if an out-of-memory situation occurred, it was typically necessary to restart the application, turn on diagnostic functions (like -verbose:gc) to determine the memory usage trend, identify the symptoms and diagnose memory problems.

Although there are tools available to diagnose memory problems, they often require a restart of the application to collect the necessary information.

The SAP JVM stores additional information when an OutOfMemoryError occurs in order to diagnose the memory problems. This information includes the following:

  • Detail message for the OutOfMemoryError.

    An OutOfMemoryError is often a confusing error, because it does not clearly identify the root cause of the error. It often only states that an error occurred. The improved detail message of the OutOfMemoryError looks similar to Exception in thread "main" java.lang.OutOfMemoryError: Java heap space (failed to allocate 1048592 bytes) and includes the memory area (for example, Java heap) in which the shortage occurred, the number of bytes which were tried to be allocated and the stack trace where the allocation happened.

  • A dump of the GC history.

    The GC history dump summarizes the activities of the GCs which happen in the VM. It shows whether a GC was a full or partial GC, how long it lasted, the number of freed bytes and many other things. It is useful to determine the memory usage trend of the system (is the heap growing slowly or quickly, in which time frame). This feature can be activated with the VM option –XX:+DumpGCHistoryOnOutOfMemory.

  • A dump of the class statistic.

    The class statistic summarizes the objects found in the generations of the Java heap. It can display the number and the cumulated size of the objects in specific generations. This allows you to identify the classes of objects that 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. This feature can be activated with the VM option –XX:+DumpDetailedClassStatisticOnOutOfMemory

  • A dump of the Java Heap.

    The Java heap can be analyzed for memory leaks with tools like jhat or the SAP Memory Analyzer. This feature can be activated with the VM option –XX:+HeapDumpOnOutOfMemoryError