tags:

views:

77

answers:

4

This is an old problem I've always had. I want to redeploy in development environment. After some deployments I run out of permgen and have to kill the server. Years ago I tried to find a solution to the problem but just found Spring and Hibernate blaming each other for the problem. Has any solution been found?

Spring Roo claims it doesn't generate classes at runtime so it wouldn't be a problem. Does it really work and if it does, how can I configure my application like that?

I realize there are two questions here but if you can answer one it is enough :)

+2  A: 

There isn't really a practical solution to this one. The reality is that every time you hot-deploy your app, you get a memory leak in the PermGen pool. How bad this leak is seems to depend on how much class generations goes on inside the app, but they all suffer from it to some degree. Apparently it's due to a design issue in the Sun Hotspot JVM, but I'm not 100% convinced of this, it seems a bit convenient to put the blame there.

You're right in that the Finger Of Blame(tm) tends to get used a lot. Spring blames Hibernate, Hibernate blames JBoss, JBoss blames Apache Commons, and so on. Noone really understands the issue, it seems, and just passes the buck.

In dev, the easiest solution is just to jack up the size of the permgen pool to a very high value. In production, you can do the same, but you shouldn't really be doing hot deployments anyway, it leads to gradual instability in most cases.

skaffman
A: 

There are a couple of things that can help with this some. Spring has a "IntrospectionCleanupListener" that can help a little. If you are loading and creating JDBC connections within the web app you can have a servlet context listener that will deregister the drivers you loaded in the app. These help, but do not entirely fix the problem.

mezmo
+3  A: 

As far as I understand it, typical PermGen storage leaks go like this.

  1. Somewhere there is a reachable reference to some object whose class has been replaced by a hot deployment.

  2. That object has a reference to its Class descriptor.

  3. The Class descriptor has a reference to its ClassLoader.

  4. The ClassLoader has references to the Class descriptors for all classes that it has loaded.

  5. Each Class descriptors has references to the classes statics frame, its bytecodes, its native code, and so on.

Just one reference to one object is sufficient to cause the permgen leak. If could be an enum value, a listener that hasn't been unregistered, ...

EDIT

The normal approach taken by people who encounter this problem is to shrug their shoulders and increase the PermGen heap size. If you really need to fix the problem for your web application(s), then:

  • Look at the way that your webapp shuts down, making sure that database connections / connection pools are closed, all callbacks are unregistered, etc.
  • Use a Java memory profiler to trace the PermGen (and other) memory leaks triggered by a redeployment.
  • Be prepared to repeat the process if new leaks are introduced as your webapp evolves.

I don't know if there are specific issues with Hibernate, but any complicated framework is potentially susceptible to this kind of problem, either on its own or in combination with application code.

Stephen C
Do you know if this always happens when using Hibernate, or it's a mistake I might have made? Is there a way to detect these kind of leaks?
palto
+1  A: 

If you are running your application under linux, running your application with the IBM JRE will solve this issue.

Christophe Petit
Does the IBM JRE support Java 6? Seems like they only support up to 1.5
palto