PermGen (Permanent Generation) is a peculiar piece of memory allocated for running JVM-based applications. PermGen error is one from the java.lang.OutOfMemoryError family, and it's an indication of a resource (memory) exhaustion.
In this quick tutorial, we'll look at what causes the java.lang.OutOfMemoryError: Permgen space error and how it can be solved.
2. Java Memory Types
The JVM works with two types of memory: the stack and the heap. The stack is used only to store primitive types and object addresses. The heap instead contains the value of the objects. When we talk about memory errors, we always refer to the heap. PermGen is, in fact, part of the heap memory but is separated and handled differently from the main memory of the JVM. The most important concept to grasp is that it is possible to have a lot of available space remaining in a heap and still running out of perm gen memory.
The principal scope of the PermGen is to store the static content of a Java Application Runtime: in particular, among other things, it contains static methods, static variables, references to static objects, and class files.
3. java.lang.OutOfMemoryError: PermGen
Simply put, this error occurs when the space allocated for the PermGen is no longer capable of storing objects. This happens because PermGen is not dynamically allocated and has a fixed maximum capability. The default size is 82 Mb for 64-bit version JVM and 64 Mb for old 32-bit JVM.
One of the most frequent reasons for the exhaustion of the PemGen is memory leaks related to classloaders. In fact, PermGen contains class files, and classloaders are responsible for loading Java Classes. Classloader issues are frequent in application servers where multiple classloaders are instantiated to achieve the independent deployment of various applications.
Problems arise when an application gets undeployed, and the server container keeps a reference of one or more classes. If this happens, the class loader itself cannot be garbage collected, thus saturating the PermGen memory with his class files. Another common reason for PermGen breakdown is application threads that continue to run after an application gets undeployed, thus maintaining several objects allocated in memory.
4. Dealing with the Error
4.1. Tune the Right JVM parameters
The first thing to do regarding limited memory spaces is to increase that space if possible. By using specific flags, the default size of the PermGen space can be increased. Big applications with thousands of classes or a huge number of Java Strings usually need a bigger PermGen space. By using the JVM parameter –XX:MaxPermSize is possible to specify a bigger space to allocate for this memory area.
Since we mentioned JVM flags, It's also worth mentioning a not-so-used flag that can trigger this error. The –Xnoclassgc JVM parameter, when specified at the start of the JVM, explicitly removes class files from the list of entities to be trashed. In application servers and with modern frameworks that load and unload classes thousands of times per application's lifecycle, this can bring to very fast exhaustion of the PermGen space.
In older versions of Java, classes are a permanent part of the heap, meaning that once loaded, they remain in memory. By specifying the CMSClassUnloadingEnabled (for Java 1.5 or CMSPermGenSweepingEnabled for Java 1.6) JVM Parameter, it is possible to enable the garbage collection of classes. If we happen to be working with Java 1.6, UseConcMarkSweepGC must also be set to true. Otherwise, the CMSClassUnloadingEnabled argument would be ignored.
4.2. Upgrading to JVM 8+
Another way of fixing this kind of error is by upgrading to a newer version of Java. Starting with Java version 8, Permgen has been entirely replaced by Metaspace, which has an automatically resizable space and an advanced feature that enables the cleaning of dead classes.
4.3. Heap Analysis
It should be trivial noticing that in case of a memory leak, none of the solutions provided can suffice. Memory will finish, no matter how great the size. Even Metaspace has a limited amount of memory available. Deep HEAP analysis is sometimes the only solution and can be conducted with tools like VisualGC or JPROFILER.
In this quick write-up, we have seen the purpose of PermGen memory and the main difference with heap memory. Next, we have seen what the java.lang.OutOfMemoryError: Permgen error means and in what peculiar cases gets triggered. In the last section, we focused on the various solutions we can put into play when trying to solve this peculiar problem.