5

We've been pushing the permgen memory space in our app higher and higher and I'm trying to find out if we have a leak of some sort eating into the permgen area. We don't do hot undeploy/redeploy actions, but we have plenty of proxies, both dynamic and CGLIB-generated. We also do some complicated classloader bits to support various use cases, and I'm suspecting that these might also be a possible contributor to permgen wastage.

So I run jmap -permstat on our running app, hoping to get some insight into what might be filling up our permgen space. (I also run a normal heap dump with both live and dead objects so I can trace down clues that might come from the permstat output).

However, out of the 2400 classloaders listed by jmap permstat, ALL but the bootstrap classloader are listed as "dead". This doesn't make sense, since the app is definitely live, and working.

My understanding was that jmap would report a classloader as "dead" if it were eligible for garbage collection but I must be wrong here...

What am I missing? What does "dead" mean here? Googling around doesn't provide a lot of answers other than the possible misunderstanding that I have here.

Scott
  • 888
  • 7
  • 21
  • 1
    This blogentry might be interesting: http://drorbr.blogspot.com/2008/11/javalangoutofmemoryerror-permgen-space.html Dead means it should be ready to be GC'ed (but obviously they arent). So there is a more then possible correlation to your leak. Otherwise i saw a neat Tool on the Eclipse-Days for Helios, the MAT. http://eclipse.org/mat A powerful tool for investigating memory leaks. Perhaps that helps. Best regards, Daniel Leschkowski – Daniel Leschkowski Jul 11 '11 at 22:32
  • Please post your VM version and java arguments – jtoberon Jul 12 '11 at 02:35
  • java version "1.6.0_21" Java(TM) SE Runtime Environment (build 1.6.0_21-b06) Java HotSpot(TM) 64-Bit Server VM (build 17.0-b16, mixed mode) – Scott Jul 13 '11 at 15:10
  • I know this might not help, but I'd upgrade to 1.6.0_26. You certainly are welcome to look through their [release notes](http://www.oracle.com/technetwork/java/javase/releasenotes-136954.html) before trying the upgrade, but if your repro case runs quickly, then just do it. Also, what VM arguments do you pass when calling `java`? – jtoberon Jul 13 '11 at 18:49
  • I also see this in my `jmap -permstat`. Sometimes -permstat gets an Exception while calculating "liveness". In that case I guess it just fails to find some path to the classloaders. But perhaps the dead? flag is not based on "unloadable" but on "class loader itself nur reachable". Dont know. I can only recommend using a heapdump (and MAT) to find the leaks as well. – eckes Oct 03 '12 at 02:21
  • I am facing a simiar issue, CGlib and BeanUtils seems to be the culprit for me. Did you find any solution eventually? – Jugal Shah Apr 24 '14 at 08:13

1 Answers1

1

Here are a few ideas:

  1. Upgrade to the latest VM.
  2. If for some reason you're running with -XX:+UseConcMarkSweepGC, then make sure you're also using -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled
  3. Do a "Reference Chains from Rootset" in jhat in order to see who’s holding the instance. Remember to exclude weak refs!
  4. This long post is a little complicated, and I haven't tried it myself, but maybe it'll help you.
  5. Try another VM, e.g. JRockit
jtoberon
  • 8,706
  • 1
  • 35
  • 48