8.10.2011

This is the part 1 of a series of posts that will provide you with a root cause analysis approach and resolution guide for Java EE OutOfMemoryError problems.

The part 1 will focus on how you can first isolate the problem and identify which JVM memory space ran out of memory.

OutOfMemoryError: What is it?

This is one of the most common problem you can face when supporting or developing Java EE production systems or a standalone Java application.

An OutOfMemoryError is thrown by the Java VM when it cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.

The actual Java Exception returned by the JVM is java.lang.OutOfMemoryError which is part of the java.lang.Error Exception list. The error message provided by the VM will be different depending of your JVM vendor and version and depending of which memory space is depleted.

Find below an example of OutOfMemoryError thrown by a Java HotSpot VM 1.6 following the depletion of the Java Heap space.

Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded

at java.util.Arrays.copyOf(Arrays.java:2882)

at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100)

at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:390)

at java.lang.StringBuilder.append(StringBuilder.java:119)

at sun.security.util.ManifestDigester.<init>(ManifestDigester.java:117)

at java.util.jar.JarVerifier.processEntry(JarVerifier.java:250)

at java.util.jar.JarVerifier.update(JarVerifier.java:188)

at java.util.jar.JarFile.initializeVerifier(JarFile.java:321)

at java.util.jar.JarFile.getInputStream(JarFile.java:386)

at org.jboss.virtual.plugins.context.zip.ZipFileWrapper.openStream(ZipFileWrapper.java:215)

at org.jboss.virtual.plugins.context.zip.ZipEntryContext.openStream(ZipEntryContext.java:1084)

at org.jboss.virtual.plugins.context.zip.ZipEntryHandler.openStream(ZipEntryHandler.java:154)

at org.jboss.virtual.VirtualFile.openStream(VirtualFile.java:241)

Analysis step #1 - Identify which JVM memory space ran out of memory

The first step is to determine which memory space is depleted. The analysis approach will depend on which JVM vendor and version you are using. I have built a quick matrix guide to help with this task. Please simply review each of the affected memory spaces below and determine which one is applicable in your situation.

Please feel free to post any comment or question if you are still having doubts with these problem isolation steps.

Review the OutOfMemoryError
message. It should give you information
such as java.lang.OutOfMemoryError: Java
heap space.

If you are not seeing any
explicit error message then you need to analyze the OutOfMemoryError
Stack Trace. Look at the first 5 lines; it will give you the type
of Java operation the Thread was executing that lead to
the OOM error. Java Heap depletion will be
triggered by Java operations such as population of a
StringBuffer, adding objects in a HashMap data structure etc.

If you are not sure about
either #1 or #2 approaches then you will
need to enable the JVM verbose GC (-verbose:gc) in
order to identify and confirm if Java Heap
depletion (Young / Old Gen) is your problem.

Problem Patterns

The Java Heap is the most common
memory space that you will face OutOfMemoryError since it is storing your Java
program short and long term Object instances.

The most common problem is a lack
of proper maximum capacity (via -Xmx argument). Java Heap memory leaks are also
quite common and will require you to analyze the JVM Heap Dump to pinpoint the
root cause.

Review the OutOfMemoryError
message. It should give you information such asjava.lang.OutOfMemoryError: PermGen
full.

If you are not seeing any
explicit error message then you need to analyze the OutOfMemoryError
Stack Trace. Look at the first 5 lines; it will give you the type
of Java operation the Thread was executing that lead to the PermGen depletion. Java PermGen space depletion will
be triggered by JVM operations such loading a class to a class loader
as per below example.

If you are not sure about either #1 or #2 approaches then you will need to enable the JVM verbose GC (-verbose:gc) in order to identifyif PermGen space depletion is your problem.

The Java HotSpot PermGen space is
the second most common memory space that you will face OutOfMemoryError since
it is storing your Java program Class descriptor related objects.

Configuring a PermGen space too
small vs. your Java / Java EE program size if the most common problem. Other scenarios include class
loader leak that can be triggered for example by too many deploy / undeploy
without JVM restart.

JVM Memory Space: Native Heap (C-Heap)

Applicable JVM vendors

·Oracle Java HotSpot (any version)

·IBM Java J9 (any version)

·Oracle JRockit (any version)

Analysis ApproachNative OutOfMemoryError error messages are normally not very informative. A deeper analysis of the
OutOfMemoryError Stack Trace is required.

Native Heap depletion will be triggered by Java operation such as loading a JAR file (MMAP file), trying to create a new Java Thread etc. which all requires enough native memory available to the C-Heap. Find below an example of OutOfMemoryError due to Native memory depletion of a 32-bit VM:

java.lang.OutOfMemoryError

at java.util.zip.ZipFile.open(Native Method)

at
java.util.zip.ZipFile.<init>(ZipFile.java:203)

at
java.util.jar.JarFile.<init>(JarFile.java:132)

at java.util.jar.JarFile.<init>(JarFile.java:97)

at
weblogic.utils.jars.JarFileDelegate.<init>(JarFileDelegate.java:32)