Resolving OutOfMemoryError: PermGen Space Issues


In this article, we’ll look at the Java error java.lang.outofmemoryerror: PermGen Space Issues
. This message is only seen when we’re using Java 7 or earlier. From Java 8 onwards, the Permgen (Permanent Generation) has been replaced by the Metaspace.
What causes this error? How do we troubleshoot the problem, and what solutions should we consider? In this article, we’ll try to answer these questions.
What is the Permgen in JVM Memory?
In Java versions 1 to 7, the PermGen was a JVM-managed memory pool that was not, strictly speaking, part of the heap.
Fig: JVM Memory in Java 7 and Earlier
JVM-managed memory consisted of the heap, split into Young Generation and Old Generation, and the PermGen. Thread stacks, the code cache, areas reserved for the garbage collector etc. were held in native memory. Native memory is allocated directly by the operating system, whereas JVM-managed memory is created with a specific size, which can be controlled using JVM runtime switches.
From Java 8 onwards, this changed.
Fig: JVM Memory in Java 8 and Later
The Permgen was replaced by the Metaspace, which is held in native memory, and is capable of growing dynamically.
The contents of the Permgen included:
Metatdata for each class;
Byte code for each method;
String Pools;
Static Variables;
Constants.
Causes of the Error: java.lang.outofmemoryerror: PermGen Space Issues
This error can occur if any of the PermGen contents listed above are too large.
The most common cause is that the application is creating more classes than PermGen can accommodate. This often happens if classes are created dynamically, for example using Java Reflection or Groovy Scripting.
An obscure cause may be that the JVM is instantiated with the –Xnoclassgc
switch. This prevents the garbage collector from cleaning up classes that are no longer referenced.
Troubleshooting PermGen Space Issues
The first step in troubleshooting any JVM error is to examine the stack trace, which pinpoints the method where the error occurred, and traces back the program path followed to reach that point.
It’s also possible to invoke the -verbose:class
switch on the command line when we call the JVM. This displays a list of classes as they are created, either on the console or in the log file.
The HeapHero tool is a valuable aid to diagnosing most kinds of memory issues. For a detailed description of how HeapHero can be used to troubleshoot PermGen space issues, see this article: Java out of Memory Error: PermGen Space. The article contains a sample program that crashes with java.lang.outofmemoryerror: PermGen Space Issues
.
Solutions
The simplest solution is to increase the PermGen size using command line switches. The default PermGen size is 82MB in 64-bit Java, and 64MB in 32-bit Java. This can be changed using the following switches:
Initial Size:
-XX:PermSize=<size>
Maximum Size:
-XX:MaxPermSize=<size>
However, this may not be the best solution in all cases. If there is a memory leak, the error will eventually recur, no matter how large we make the PermGen. Other solutions include:
Ensure classes and large strings are dereferenced when they’re no longer needed;
Avoid very large static variables and constants;
Check for recursively-called methods that create classes dynamically;
Upgrade to Java 8 or later, which has better memory management.
Conclusion
We only see the error: java.lang.outofmemoryerror: PermGen Space Issues
in older versions of Java, because the Permgen was replaced with the Metaspace in Java 8.
The most common solution to this problem is to increase the size of the PermGen using runtime switches. We also need to check for memory leaks. Upgrading to Java 8 or later often solves the problem, since the Metaspace is able to grow dynamically.
I hope you found this article useful. Your comments would be appreciated.
Subscribe to my newsletter
Read articles from Jill Thornhill directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
