Understanding and avoiding the Java Permgen Space error
In this article, I look into what it means when a Java program runs into a OutOfMemoryError: PermGen Space error. I first explain what the permanent generation heap space is, after which I explain the usual cause of the Permgen Space error and I give some pointers on how to avoid it.
Introduction
Usually, we do not look into JVM intrinsics. We take the JVM as is.
Some of the world’s finest engineers are working on the JVM(s) and I am sure we can’t improve their work, definitely not without getting seriously involved.
However, as a Java developer, you are often confronted with performance issues, usually working memory related.
The problem I run into most is the dreaded OutOfMemoryError: PermGen Space error. I thought it would be nice to know more about it, so I looked into what causes it exactly.
Java memory structure
To understand the error, we have to look into how the jvm memory is structured.
There are two memory regions in the JVM: the heap and the stack. Local variables and methods reside on the stack, everything else on the heap.
This Java heap memory is structured again into regions, called generations. The longer an object lives, the higher the chance it will be promoted to an older generation. Young generations(such as Eden on Sun JVM) are more garbage collected than older generations(survivor and tenured on Sun JVM). However, there is also some separate heap space called permanent generation. Since it is a separate region, it is not considered part of the Java Heap space. Objects in this space are relatively permanent. Class definitions are stored here, as are static instances.
Without getting into details, Classloaders deploy and undeploy classes all the time. For example, this happens when an application is deployed or undeployed on a webserver. On web servers, all applications have their own Classloader. When an application is deployed or undeployed, its class definitions and Classloader are respectively put into and removed from the permanent generation heap.
OutOfMemoryError: PermGen Space
The OutOfMemoryError: PermGen Space error occurs when the permanent generation heap is full. Although this error can occur in normal circumstances, usually, this error is caused by a memory leak.
In short, such a memory leak means that a classloader and its classes cannot be garbage collected after they have been undeployed/discarded.
To give an example on how this can happen, let’s say we have a Payment class, which is part of a jar in a web application that is deployed on some webserver. In the lib folder of the web server, there is some logging framework present, which has a Log class with the method register(Class clazz) with which classes can be registered for logging. Let’s say that the Payment class gets registered by this method and the Log class starts keeping a reference to the clazz object. When the Payment class gets undeployed, it is still registered with the Log class. The Log class will still have a reference to it and hence, it will never be garbage collected. Moreover, since the Payment Class has a reference to its ClassLoader in turn, the ClassLoader itself will never be garbage collected either, and so will none of the classes it loaded.
An even more typical example is with the use of proxy objects. Spring and Hibernate often make proxies of certain classes. Such proxy classes are loaded by a classloader as well, and often, the generated class definitions – which are loaded like classes and stored in permanent generation heap space – are never discarded, which causes the permanent generation heap space to fill up.
Avoiding the error
1. Increasing the maximum size of the permgen heap
The first thing one can do is to make the size of the permanent generation heap space bigger.
This cannot be done with the usual –Xms(set initial heap size) and –Xmx(set maximum heap size) JVM arguments, since as mentioned, the permanent generation heap space is entirely separate from the regular Java Heap space, and these arguments set the space for this regular Java heap space. However, there are similar arguments which can be used(at least with the Sun/OpenJDK jvms) to make the size of the permanent generation heap bigger:
-XX:MaxPermSize=256m
would set its maximum size to 256m, which is 4 times bigger than the default size.
2. Use common sense when using static fields on classes.
Make sure you do not write classes that have static variables keeping references to class definitions and the like.
Using JDK dynamic proxies instead of cglib proxies
So using jdk dynamic proxies instead of cglib might be a good idea when getting the error.
Also, newer versions of Hibernate appear to not use cglib as a bytecode provider anymore, so upgrading your version of Hibernate, might drastically lower your chances on getting the error.
Summary
In general, when getting the error, one needs to determine why certain class definitions are not garbage collected. Once that is known, it should be possible to battle the error.
Thanks a lot..!!! This article helped me a lot in understanding @PERMGEN error.
Was this answer helpful?
LikeDislikeVery good explanation about JVM memory stucture…. Thanks!!!!!!!
Was this answer helpful?
LikeDislikeSimple and nice article to get to know about JVM memory usage.
Was this answer helpful?
LikeDislikeExcellent Explaination. Thank u very much.
Was this answer helpful?
LikeDislikeGreat Post! Helped me Understand PermGenSpace
Was this answer helpful?
LikeDislikevery very good explanation for PermGen problem……..
The perm-space is not part of the heap. The meta-data on classes, interfaces and their methods that is housed there does is never “garbage collected” (perhaps this is implementation dependent). I would hesitate to call this a memory leak.
The perm-space does not grow without bound. Once you’ve warmed up your application (you have referenced most if not all the classes an interfaces you use) you hit a limit. Given the precious nature of memory, squandering 25%, 50% or more on perm-space should not be done in production. I would use jconsole (comes with JDK) and make a note of how much perm-space you use after running through your application.
One caveat is that if you have multiple web-apps, each has it’s own class loader and the class loader is part of the “type” (that’s how types are isolated) across applications. Also, if you hot deploy new instances, I suspect that will increase your perm-space, too. Anyway, you can use jconsole to watch for that.
Was this answer helpful?
LikeDislikeVery good explanation.
Was this answer helpful?
LikeDislikeThanks a lot! This was very useful in solving the PermGen issue.
Was this answer helpful?
LikeDislikeThanx…
Was this answer helpful?
LikeDislikeThanks!
Was this answer helpful?
LikeDislikeGreat Article !!
Was this answer helpful?
LikeDislikeSimple and effective. Bunch of Thanks!
Was this answer helpful?
LikeDislikeThank you, very nice explanation
Was this answer helpful?
LikeDislikeNice article, Steffen!
Was this answer helpful?
LikeDislikeAwesome explanation Steffan…..really got to learn a lot….thnx..:-)
Was this answer helpful?
LikeDislikeReally very good article ..thnkx for posting it out
Was this answer helpful?
LikeDislikeIt was nice explanation… Is there any way to identify, what caused PermGen Space error in web application
Was this answer helpful?
LikeDislikeAwesome Steffen!!!!!!!!!
I have never seen such a clear explanation for heap and perm space.
It would really help in my carrier while troubleshooting the out of memory Error.
Thanks,
Guru R
Was this answer helpful?
LikeDislikeThanks for the wonderful post. Helped me to gain knowledge on Memory structure.
Was this answer helpful?
LikeDislikeThanks for the Article, Steffen The concept is more clear now..!!
Was this answer helpful?
LikeDislikeGood One!
Was this answer helpful?
LikeDislikeThanks for helpful article.
Was this answer helpful?
LikeDislikeThank you for explaining the issues in a simple way.
Was this answer helpful?
LikeDislikeGreat article Steffen.
Was this answer helpful?
LikeDislikeGood article, it really help us
Was this answer helpful?
LikeDislikegreat article…hats off to your work
Was this answer helpful?
LikeDislikenice article..!!
Was this answer helpful?
LikeDislikeThanks for sharing useful information on PremGen memory. Also I found on researching PremGen that, we can manage PremGen memory by enable CMSClassUnloadingEnabled the GC will sweep PermGen and remove classes which are no longer used.
Was this answer helpful?
LikeDislikeNice explanation…Thanks
Was this answer helpful?
LikeDislikeExcelent article. Thank you very much for posting.
Was this answer helpful?
LikeDislikeAwesome Steffen!!!!!!!!!
I have never seen such a clear explanation for heap and perm space.
It would really help in my carrier while troubleshooting the out of memory Error.
Was this answer helpful?
LikeDislikeVery good explanation!!
Was this answer helpful?
LikeDislikeVery nice and more understandable explaination…
Was this answer helpful?
LikeDislikeThanks a lot. This article is great insight on JVM memory structure!
Was this answer helpful?
LikeDislikeThanks for sharing!
Was this answer helpful?
LikeDislike