Skip to content

Understanding java.lang.OutOfMemoryError: PermGen space

This error has been floated on every other forum. They say, it’s an incomplete garbage collection sweep where resources are not properly released upon unload/restart. The ubiquitous solution “seems” to be – Increase your heap size! I started reading more about it and this is what I gather from a lot of forums and articles: -

So you increase the heap size in your eclipse or server run.bat with something like this: -
-Xms512m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512

It does help prevent for sometime. But you got it again. Now, who’s the SonOfAGun, who suggested you to change the heap size?

But think for yourself. Do you think that solves the problem? It’s like telling your girlfriend – “Increase the credit limit of your credit card,” to cope up with her shopping debts. The above solution is exactly, what it is. The problem is not with increasing the credit limit, but by telling your gf to clear off your bills in time or even better, find a source of income that automatically pays of the debts.

The Sun JVM uses the permanent generation to store class files, but the permanent generation is not sweeped by the garbage collector. Say, each time you redeploy your app, the permanant generation gets bigger and eventually it bursts, regardless of how big you make it. A bigger size just prolongs the inevitable.

You have two options. You can enable sweeping of the permanent generation.
-XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled

OR, you can switch to a JVM that does not use a permanent generation (or doesn’t use it to store class files) like the IBM JVM. It seems, you can run the IBM JVM in production for 2 years and never get an out of memory error. The problem is not with Tomcat or JBoss AS or Spring or Hibernate. The problem is with the garbage collector strategy not aligning with how web applications are redeployed.

For a technical overview – Frank Kieviet explains quite remarkably on the root cause of this error, from a class loader point of view. I recommend you read it before you have any further assumptions.

How can you avoid it?

  • For development modes, try not to redeploy your war/ear frequently without stopping the server — quick and dirty. (actually this would be bad, as you’ll never find that there is a leak in your code).
  • If you really want to get to the core (of your gf’s spending habits), follow Frank’s blog to detect a classloader leak.
  • Switch to JRockIt, BEA’s JVM implementation, that virtually eliminates this error. (Yeah, I know you must be saying — “It’s easier to convince my gf than your Dev Manager to switch JVM’s altogether!”)
  • The most common thing in the permanent generation is classes, so one cause of OOM in permgen is that new classes get added, and old ones aren’t getting GCed. Since JProbe can show you instances of classes, and references to them, it can be helpful in finding out why they aren’t being GCed. It can be very tricky to follow all the references, though.
  • Using command-line Java options to investigate
    - Make sure you’re not using -Xnoclassgc or classes won’t get GCed at all
    - Use -XX:-UseSharedSpaces since that partitions the permgen for class sharing, and it might be simpler to track if you’re just using a single space.
    - Add -verbose:class -XX:+PrintGCDetails which should show both class loading and unloading, as well as the size of the permgen at GC. That may help you understand what it’s filling up with.
  • JProbe – Run your app server under JProbe, and take a heap snapshot before the OOM (which will happen sooner than normal; JProbe uses some extra permgen space since it instruments classes). From the Instances view, double-click the java.lang.Class row to bring you to the Instance Detail View. Now the painful part: look for classes you would have expected to have been GCed, and use the referrer tree, reference graph, or Leak Doctor to try to figure out why it’s still there.The bottomline is, you’ll really need to find out why that object is still around, as it’s referenced somewhere.

It’s not going to be easy … and if still no luck, I’d say, dump the btich and find a new gf

Relatd Blogs:

eclipsezone
explaining OutOfMemoryError
Jon Masamitsu’s tutorial

Reference Tools
jvmstat
JProbe Analyzer
Memory Analyzer using Eclipse

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*