views:

34572

answers:

14

Recently I ran into this error in my web application:

java.lang.OutOfMemoryError: PermGen space

It's a typical Hibernate/JPA + IceFaces/JSF application running on Tomcat 6 and JDK 1.6.

Apparently this can occur after redeploying an application a few times.

+26  A: 

The solution was to add these flags to JVM command line when Tomcat is started:

-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

You can do that by shutting down the tomcat service, then going into the Tomcat/bin directory and running tomcat6w.exe. Under the "Java" tab, add the arguments to the "Java Options" box. Click "OK" and then restart the service.

Source: orx's comment on Eric's Agile Answers.

Chris
The article below suggests -XX:+UseConcMarkSweepGC and -XX:MaxPermSize=128m as well.http://my.opera.com/karmazilla/blog/2007/03/13/good-riddance-permgen-outofmemoryerror
Taylor Leese
You sir are a king - this problem's been bugging me for ages. Thanks muchly!
Chris Harcourt
-XX:+CMSPermGenSweepingEnabled This option brings down performance. It makes each request take three times more time than usual on our systems. Use with care.
Ubersoldat
+2  A: 

Alternatively, you can switch to JRockit which handling permgen differently then sun's jvm. It generally has better performance as well.

http://www.bea.com/jrockit/

Jeremy
+1  A: 

JRockit resolved this for me as well; however, I noticed that servlet restart times were much worse, so while it was better in production, it was kind of a drag in developemnt.

Tim Howland
+3  A: 

use the command line parameter -XX:MaxPermGen=128m for a Sun JVM. (obviously substituting 128 for whatever size you need)

The only issue is that you're just delaying the inevitable- at some point you'll run out of headroom there too. It's a great pragmatic solution, but it doesn't solve it permanently.
Tim Howland
same thing occurs in Eclipse and any time you have lots of dynamic class loading. the classloaders aren't disposed of and live in the permanent generation for all eternity
Matt
Actually I think the correct switch is -XX:MaxPermSize
matt b
+1  A: 

I still keep getting the error despite trying the

-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

I have also tried

-XX:MaxPermGen=128m

Nothing seems to work on my Sun JDK 1.6.0_12, Any clue? Should move to Jrockit JVM

I believe that these flags only delay the inevitable, they don't cure the problem.
matt b
+2  A: 

Try -XX:MaxPermGen=256m and if it persists, try -XX:MaxPermGen=512m

A: 

The configuration of the memory depends on the nature of your app.

What are you doing?

What's the amount of transactions precessed?

How much data are you loading?

etc.

etc.

etc

Probably you could profile your app and start cleaning up some modules from your app.

Apparently this can occur after redeploying an application a few times

Tomcat has hot deploy but it consumes memory. Try restarting your container once in a while. Also you will need to know the amount of memory needed to run in production mode, this seems a good time for that research.

OscarRyz
+10  A: 

You better try -XX:MaxPermSize=128M rather than -XX:MaxPermGen=128M.

I can not tell the precise use of this memory pool, but it have to do with the number of classes loaded into the JVM. (Thus enabling class unloading for tomcat can resolve the problem.) If your applications generates and compiles classes on the run it is more likely to need a memory pool bigger than the default.

A: 

I have a combination of Hibernate+Eclipse RCP, tried using -XX:MaxPermSize=512m and -XX:PermSize=512m and it seems to be working for me.

+2  A: 

I have fought this for hours, but I have no good news.

See my related question: http://stackoverflow.com/questions/1996088/java-class-permgen-memory-leak-web-applications-generic-solution

You may still have a memory leak, e.g. classes are not garbage collected because your WebAppClassLoader is not garbage collected (it has an external reference that is not cleared). increasing the PermGen will only delay the OutOfMemoryError, and allowing class garbage collection is a precondition, but will not garbage collect classes if their class loader still has references to it.

Ehrann Mehdan
A: 

set -XX:PermSize=64m -XX:MaxPermSize=128m Later on you may also try increasing MaxPermSize. Hope it'll work. The same work for me. Setting only MaxPermSize didn't worked for me.

sandeep
A: 

They Say that the latest rev of Tomcat (6.0.28 or 6.0.29) handles the task of redeploying servlets much better.

Tony Ennis
A: 

"They" are wrong because I'm running 6.0.29 and have the same problem even after setting all of the options. As Tim Howland said above, these options only put off the inevitable. They allow me to redeploy 3 times before hitting the error instead of every time I redeploy.

Ross Peoples