25

I want to get a dump of the PermGen to see why it is filling. Is there a way to analyze this? I already know about the common suspects like log4j, tomcat webapp reloading etc, but I have some custom proxy generation code in my application, too, and just want to look under the hood.

Is this possible somehow?

Daniel
  • 27,718
  • 20
  • 89
  • 133

4 Answers4

26

The PermGen normally consists of the string literal pool and loaded classes. To answer part of your problem, i.e. the string literal pool I wrote a utility to print a running JVM's string literal pool. It is available here:

https://github.com/puneetlakhina/javautils/blob/master/src/com/blogspot/sahyog/PrintStringTable.java

It is based on PermStat, which is the class used to print permgen stats by the jmap tool.

Nicolas
  • 2,321
  • 4
  • 21
  • 32
Puneet
  • 736
  • 9
  • 17
  • Great stuff! This is exactly what I needed! – Daniel Oct 02 '11 at 18:41
  • Could you please clarify how can we fix "Attaching to process ID XXXX, please wait... Error attaching to process: Timed out while attempting to connect to debug server (please start SwDbgSrv.exe)." on Windows while running this program? – MiamiBeach Apr 14 '15 at 14:21
18

You can use the flags:

-XX:+TraceClassLoading -XX:+TraceClassUnloading

They print the identities of classes as they get loaded/unloaded from the permanent generation. If you add -XX:+PrintGCDetails you can also track the size of the permgen.

Note that i'm not sure the flags are supported in JVMs other than Sun's.

Another suspect of PermGen out-of-memory-errors is string interning. Check the places where you intern strings in your code.

bluish
  • 26,356
  • 27
  • 122
  • 180
Eyal Schneider
  • 22,166
  • 5
  • 47
  • 78
  • 2
    This does not address the actual question ... how to **dump** the permgen heap. – Stephen C May 16 '10 at 09:07
  • @Stephen: you are right, but I hoped it would be enough in this case :) – Eyal Schneider May 16 '10 at 15:32
  • accepted, because this helped me most, even if it did not completly solve my problem. I found out that 160MB pern gen really were not much enought, after writing a script that parsed my log output and counted the size of all loaded classes. (While reading my comment I see at least 2 WTFs) – Daniel May 21 '10 at 19:29
4

If you're looking to get a list of all classes loaded you can use jconsole. Click on the classes tab then click "Verbose Output". That will print each class that is loaded to stdout. I found this very useful tracking down a JAXB proxy class issue.

You may have to launch your application with the -Dcom.sun.management.jmxremote command line option in order for jconsole to attach to it.

mtpettyp
  • 5,533
  • 1
  • 33
  • 33
  • Sorry, my permgen is already nearly full. And I don't know with what. – Daniel May 17 '10 at 05:12
  • This should print out the classes that are filling your PermGen space as they are loaded. Can you restart your application and turn on this logging? – mtpettyp May 17 '10 at 14:02
  • Not useful and in fact the same as providing -XX:+TraceClassLoading -XX:+TraceClassUnloading from the first comment. – Daniel May 21 '10 at 19:27
4

Will jmap -permgen fit the bill?

See the troubleshooting guide for Java http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/memleaks.html#gbyuu

Dilum Ranatunga
  • 13,254
  • 3
  • 41
  • 52
  • No. I already knew about this, but I really need a way to have a look at whats already in there. – Daniel May 17 '10 at 13:06
  • 1
    Tried using `-permstat` but just got: `Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process` – Jesse Glick Sep 22 '14 at 14:02