/ OutOfMemoryError Help Guide – Part 1 ~ Java EE Support Patterns

8.10.2011

OutOfMemoryError Help Guide – Part 1

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.

Affected Memory Space
Applicable JVM’s
Analysis approach
Problem Patterns
Java Heap
- Sun Java HotSpot (any version)

- IBM Java VM (any version)

- Oracle JRockit (any version)
1) Review the OutOfMemoryError message. 
It should give you information such as
java.lang.OutOfMemoryError: Java heap space.

2) 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.

3) 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.
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.
PermGen
- Sun Java HotSpot (1.4, 1.5, 1.6)


** Please note that the PermGen space is not applicable for either the IBM or JRockit VM **
1) Review the OutOfMemoryError message. It should 
give you information 
such as java.lang.OutOfMemoryError: PermGen full.

2) 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.

java.lang.OutOfMemoryError: PermGen space
  at java.lang.ClassLoader.defineClass1(Native Method)
  at java.lang.ClassLoader.defineClass(Unknown Source)
   ..........................................................................................

3) 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 if 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.
Native Heap
 (C-Heap)
- Sun Java HotSpot (any version)

- IBM Java VM (any version)

- Oracle JRockit (any version)
1) Native 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)
       .......................................................................
An OutOfMemoryError resulting from a Native Heap depletion is less common but can happen for example if you physical server is running out of virtual memory.

Other scenarios include memory leak of third party native libraries such as a monitoring agent or trying to deploy too many applications (EAR files) or Java classes to a single 32-bit JVM.


0 comments:

Post a Comment