Sunday, June 20, 2010

I've moved this blog to http://www.ericsimmerman.com/ for all future posts. 1/12/09

Eric's Agile Answers Posts on whatever your host, Eric Simmerman, deems relevant.

« Hibernate support... | Main | Anonymous access of... »
20060623 Friday June 23, 2006
Preventing Java's java.lang.OutOfMemoryError: PermGen space failure

The "OutOfMemoryError: PermGen space" message is normally encountered during development activites where a long-running JVM is asked to load/unload builds. However it can also be encountered in a recently spawned JVM under the "right" set of conditions.

The message is a symptom of an incomplete garbage collection sweep where resources are not properly released upon unload/restart. There is no shortage of debate (Hibernate forum, Sun forum, Spring Framework forum ) regarding which codebase is responsible for this symptom, but the finger of blame has been pointed at CGLIB, Hibernate, Tomcat, and even Sun's JVM.

Generally speaking, this is an interoperability issue and can be resolved by changing one of the components in your software stack. Some users have reported relief by upgrading to the latest Tomcat 5.5 release, others have simply opted for another webcontainer implementation (like Jetty or Resin) with varying degrees of success.

In my experience, the most pain-free method of resolving this issue is to switch from Sun's JDK implementation to BEA's freely available JRockit implementation.

On a recent project utilizing Tomcat 5.5.12 with Hibernate, I was plagued with this PermGen error, at times even experiencing it during web-based unit testing. Since making the switch to JRockit, I have not encountered this issue even once. I attribute the "fix" to the differences between JRockit's and Sun's garbage collection implementations, but have no proof that this is indeed the reason that JRockit resolves the issue. In any case, WFM.


Posted by ets ( Jun 23 2006, 11:23:09 AM EDT ) Permalink Comments [36]

Comments:

I also had these annoying Perm Gen Space OOMs when redeploying webapps. I'm using spring 1.2.8, Hibernate 3 (both with CGLIB 2.1_3), tomcat 5.5.17 and - now the problem: jdk1.5.0_06. After upgrading to jdk1.5.0_07 my Perm Gen Space gets gc'ed like it should be - no increase of Perm Gen Space, no code changes.

There were however some learnings on the way:

1. Put JDBC driver in common/lib (as tomcat doku says) and never ever in WEB-INF/lib - If you get No suitable driver Exception during redeploy use JNDI DB definition in META-INF/context.xml; not in server.xml and not in conf/Catalina/localhost/.xml. This is how my META-INF/context.xml looks like:






2. Don't put commons-logging into WEB-INF/lib since tomcat already bootstraps it

3. If you still run in Perm Gen Space OOM then you may have to increase Perm Gen Space or don't redeploy your webapps so fast! What was most irritating for me after thinking the issue is solved for me was that sometimes i did ran into Perm Gen Space OOM and sometimes not. It seems that gc cleans Perm Gen Space from time to time and not (!) if space is low or app explicitly requests gc. - But this I didn't fully understand (not to say not at all), but still there are reasonable arguments on sun bug database to increase this memory (see post above)

Now I'm happy again after two (!) days of reading lots of forum threads, learning lots about class loader, tomcat, spring, hibernate, aop and class metadata and knowing that programming still can be very difficult!

Posted by Yan Hackl-Feldbusch on June 29, 2006 at 04:11 AM EDT #
The problem is that Tomcat does not garbage collect the Classloader and the classes it loads. Each you reload the webapp context, more copies of these classes are loaded, and as these are stored in the permanent heap generation, it will eventually run out of memory.
The same issue could affect (and affects) to any container. You just have to restart the container instead of restarting the context.
It's easy to reproduce this problem by reloading the context over and over again until you get an OutOfMemoryError (10 times was enough for a simple app)

Cheers

Posted by Cheng Lee on August 26, 2006 at 04:36 PM EDT #
JRockit doesn't have generational garbage collection - in other words, it doesn't have permanent generation space. Therefore, it can't have PermGen errors. Ever.

That's not to say that you won't / haven't got a memory leak, and that eventually it may bring the JVM down, but it isn't reliant on a separate little hived off area like the Sun's JVM.

Posted by Graham Triggs on November 08, 2006 at 09:13 AM EST #
These problems are not specific to Tomcat, Hibernate, or Spring. I am using Glassfish on JDK 6.1, and run into this error all too frequently. If there are solutions that don't require swapping out the JDK, then please post them.

Posted by ITVGuy2000 on August 06, 2007 at 01:02 AM EDT #
-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

Posted by orx on October 12, 2007 at 12:45 PM EDT #
ok

Posted by 203.197.25.11 on November 02, 2007 at 06:11 AM EDT #
I've had large apps running on our server for more than a year now. They are built using JPOX for persistence and we've never once experienced an Out of memory, PermGen Space error.

Just recently we installed a third party app that uses Hibernate for persistence and now we get PermGen errors. I noticed that there are a number of articles pointing to PermGen memory problems/leaks with Hibernate when it is not using reflection as it burns up a bit too much memory via it's iteractions with CGLIB. The suggestion seems to be to run Hibernate in "reflection" mode but reflection is a very slow mode for any ORM to operate in.

I'm not sure if our particular problem is with Hibernate or the application itself. It's a third party open source project that we use nearly everyday. I don't want to mention it's name in case this issue is related to the Hibernate framework that it ships with and not the application itself.

It should be fairly quick to change the code to use JPOX like the rest of our apps use to see if the problem goes away. Both JPOX and Hibernate support transparent persistence so there shouldn't be any references to the any specific ORM stuff in the model code.

Anyone had experience porting between different "transparent" persistence ORMs before?

Posted by Golfman on February 08, 2008 at 03:55 PM EST #
>>The problem is that Tomcat does not garbage >>collect the Classloader and the classes it >>loads. Each you reload the webapp context, >>more copies of these classes are loaded, and >>as these are stored in the permanent heap >>generation, it will eventually run out of >>memory.
>>The same issue could affect (and affects) to >>any container. You just have to restart the >>container instead of restarting the context.
>>It's easy to reproduce this problem by >>reloading the context over and over again >>until you get an OutOfMemoryError (10 times >>was enough for a simple app)

>>Cheers
>>Posted by Cheng Lee on August 26, 2006 at >>04:36 PM EDT #

Interesting and believing this is true. Question is how to avoid this happening

Posted by 134.178.63.3 on February 21, 2008 at 05:50 PM EST #
fjkfk

Posted by 122.168.26.172 on March 06, 2008 at 11:18 AM EST #
When I ran a profiler, I noticed that by default you have 96MB of non-heap memory limit. With BEA this raises up to 4GB, so of course you can redeploy thousands of times. But still, with each redeployment, the amount of allocated memory raises again :(

Posted by Dunkelheit on March 14, 2008 at 10:07 AM EDT #
I encounter the same problem. I am using BEA Weblogic. I have removed the deployment of my application, and shutdown the managed server relating to the application. I am intending to redeploy the application, hoping to make a new clean start. But i encounter the message below.

WARNING: The server has decided to close this client connection.
<27/03/2008 11:48:46 AM EST>

How to clean up this garbage so that when i redeploy I don't encounter the same problem of OutOfMemoryError:PermGen space failure??

Posted by Joni on March 26, 2008 at 08:54 PM EDT #
I came across this error very recently, and I haven't been able to pin point whether this is happening due to only Tomcat, Hibernate or the JVM mainly because we use both Tomcat and Hibernate.

One sure way of avoiding this problem, I gather, is by restarting the container every time we re-deploy the app. It may not be practical when you have more than one app running on your server, but it works. I'm usually in the habit of restarting the server with each deployment, whereas some of my teammates are not. And until now, I've never experienced this problem, whereas my teammates have.

All in all, a good thread, with good insights thrown in from some of the readers. Thanks.

Posted by Satya on April 25, 2008 at 10:31 AM EDT #
I can confirm the solution by ITVGuy2000 perfectly works for me (1.6.0_05, Apache Tomcat 6.0.16):
-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

ITVGuy2000, Great thanks!!!

Posted by Maxym on June 18, 2008 at 11:29 AM EDT #
sorry, seems like it was Posted by orx on October 12, 2007 at 12:45 PM EDT

orx, huge THANK YOU!

Posted by Maxym on June 18, 2008 at 11:30 AM EDT #
This error occurs when the JVM runs out of space in the permanent generation heap. Since the defaults for the JVM are quite low, the first step should be to increase the default using -XX:MaxPermSize.

Put the below VM argument when starting program

-XX:MaxPermSize=256m

-------------------------------------------------


-XX:MaxPermSize=256m


Posted by xyz on July 03, 2008 at 02:11 AM EDT #
Your Comment:Your Comment:Your Comment:Your Comment:

Posted by Your Comment: on July 07, 2008 at 06:51 AM EDT #
Someone could tell me what exactly do these 2 options?

-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

Posted by Marlon Patrick on July 07, 2008 at 09:44 AM EDT #
Java PermGen space out of memory error :
Steps to rectify this error :

Hi Guys This is common error people get when they are using tomcat
for big web application .so following are the steps to rectify this error :
1.0 click on tomcat start up
2.0 click on java tab in tomcat startup
3.0 Now add the following parameter in java option field :

-XX:MaxPermSize=512m
-verbose:gc
-XX:+PrintClassHistogram

4.0 assign intial pool memory 256 mb

5.0 assign maximum memory pool 1024mb

6.0 restart the server

This setting is applicable or this is an example when your system RAM is 2GB where the tomcat

is running .

for other RAM size please make sure that memory division does not exceed to system

memory.otherwise tomcat server will not restart.


after doing aforesaid setting if you still face this issue :

please look at the tomcat server log file ,Parameter PrintClassHistogram will
print the time life of each object .so now you have to optimized your code
where the object life is more .
Hope aforesadi solution will workout your issue

Posted by ram sahai on July 17, 2008 at 12:27 AM EDT #
I am also facing the same issue ([junit] Exception in thread "Thread-0" java.lang.OutOfMemoryError: PermGen space) when I run the junit testcases using ANT utility. Tried to solve the problem setting the JVM aguments ( -XX:PermSize=1024m -XX:MaxPermSize=1024m). But it didn't worked. Finally ran junit testcases with bea JROCKIT and it worked.

Posted by Susanta Ghosh on August 19, 2008 at 12:23 PM EDT #
Thanks alot my problem also solved.

Posted by KranthiGedela on October 03, 2008 at 10:28 AM EDT #
@ Susanta Ghosh
how much RAM do you have?

Posted by mdalangin on October 05, 2008 at 11:34 AM EDT #
Hi,
I think this problem can also be due to a Leakage Class Loader.....

Check Eclipse Memory Analyzer to see the details.......

Thanks,
Nirmal

Posted by Nirmal Kumar on October 15, 2008 at 12:13 PM EDT #
add the following in Java-option under tomcar configuration and everything will be ok.

-Xmx256m
-Xms256m
-XX:PermSize=512m
-XX:MaxPermSize=512m
-verbose:gc

Posted by muzy on November 04, 2008 at 09:31 AM EST #
Switched from jrockit to Sun JDK 1.5.0_16b02 on RH5, started getting the PermGen OOM error. Adding -XX:PermSize=256 cleared it up.

Posted by Mike on November 08, 2008 at 06:51 AM EST #
F

Posted by 59.145.67.121 on November 22, 2008 at 05:18 AM EST #
Hi everyone,

I've tried with tomcat(6.0.18), glassfish(prelude v3) and hotspot(1.6.0_04-b12) + a simple spring hibernate app.

I tried -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled as well.

In both cases after 10 redeploys I get OutOfMemoryError.

Did someone managed at least to identify the problem? Is there a official bug report for sun guys?

Posted by Dusan on December 04, 2008 at 08:48 AM EST #
THIS IS MY ERROR:
12/17/2008 15:45:17 HTTP JVM: Unexpected error while executing java agent:JavaAgent
12/17/2008 15:45:17 HTTP JVM: -->java.lang.OutOfMemoryError: PermGen space
12/17/2008 15:45:17 HTTP JVM: java.lang.OutOfMemoryError: PermGen space

We have previously extend the mem space but it ended up crashing our domino server. If you have any other suggestions please send them. Kind regards.

Posted by Adele on December 17, 2008 at 09:54 AM EST #
Article provides gud information about JVM parameters

Posted by Arun on March 04, 2009 at 11:52 PM EST #
The article is good! And so does the comments. I learn a lot from both.

I happen to "hit" this kind of error in someone else application. It uses

Hibernate+Spring+WebSphere. It's turn out that the problem is on the creation of application context EVERYTIME the application run several .Java file! Can you imagine how memory-consume it was.

The solution is using the SingletonBeanFactoryLocator class.

Posted by pucha on March 12, 2009 at 05:24 AM EDT #
-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

These options only work if you are using CMS garbage collection, i.e. you must also have the JVM option:

-XX:+UseConcMarkSweepGC

Posted by vlad on September 03, 2009 at 05:25 AM EDT #
I new to this. I get the same error and I found good solutions and comments. Now I want to try

Can you guide me that which file should I update with this :
-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

Im using Tomcat 5.5

Many thanks

Posted by Mike85 on October 08, 2009 at 11:40 PM EDT #
In the case of Tomcat (Don't know how Glassfish orany other servlet container implements its undeploy) when a webapp is undeployed tomcat simply removes its reference to the WebAppClassLoader

In theory this makes all objects in the webapp unreachable go the garbage collector will remove them.

Two things can mess this up (possibly more):

1: The webapp started a thread and this thread is still running. This becomes a garbage collector root, so anything it references will not be collected

2: If a class loaded by the webapp classloader is referenced by a parent classloader that class is still reachable. All class objects contain a reference to their classloader, which make the WebAppClassLoader still reachable - and the entire webapp.

There are known points in the JVM where this can happen. One is creating a subclass of java.util.logging.Level as its constructor will add the instance to a static field of the Level class, which is typically loaded by the bootstrap classloader

There's more documents places in this class org.apache.catalina.core.JreMemoryLeakPreventionListener

Posted by Chris on December 08, 2009 at 05:18 PM EST #
Thanks for ur solution !!
Had the same problem and it got fixed when I used -XX:MaxPermSize=512m :)

Posted by tyt on March 08, 2010 at 12:07 PM EST #
We are using glassfish, jdk 1.5. During redeployment it throws memory out of error.

Posted by srinivas on March 20, 2010 at 04:12 AM EDT #
Exception in thread "GroupChannel-Heartbeat-1" java.lang.OutOfMemoryError: PermGen space

any one know abt this error . i got this error and tomcat is still loading the page for a long time

Posted by kalasagar on April 06, 2010 at 02:43 AM EDT #
My problem was fixed by putting libraries in a shared location for the web server rather than the deployed application library.

Posted by Chris on April 22, 2010 at 03:47 AM EDT #
Post a Comment:

Name:
E-Mail:
URL:
Notify me by email of new comments
Remember Information?

Your Comment:

HTML Syntax: NOT allowed

Please answer this simple math question

6 + 37 =