Tuesday, October 20, 2009

For fun, I've been looking into Java's memory management tools, jhat and jmap.

Jmap works fine. I'm running Linux, so I find the Java process that I want to analyze by using ps -ef |grep java. Then I run jmap -dump:format=b,file=java_pid.hprof pid where pid is the Java process id. This generates a heap dump. You can repeatedly do this to get snapshots of the heap over time. Neat! Some of the heap dumps are quite large, over 1G in size.

Once you've got the heap, what can you do with it? You can use jhat - at least in theory. According to the jhat documentation, "jhat enables you to browse heap dumps using your favorite webbrowser." Sounds cool! But when I attempt to run it, I always get an OutOfMemoryError:

me@me:~/heaps$ ~/jdk1.6.0_10/bin/jhat java_pid403M.hprof
Reading from java_pid403M.hprof...
Dump file created Sun Oct 18 10:17:15 PST 2009
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Hashtable.rehash(Hashtable.java:356)
at java.util.Hashtable.put(Hashtable.java:412)
at com.sun.tools.hat.internal.model.Snapshot.addHeapObject(Snapshot.java:153)
at com.sun.tools.hat.internal.parser.HprofReader.readInstance(HprofReader.java:728)
at com.sun.tools.hat.internal.parser.HprofReader.readHeapDump(HprofReader.java:474)
at com.sun.tools.hat.internal.parser.HprofReader.read(HprofReader.java:226)
at com.sun.tools.hat.internal.parser.Reader.readFile(Reader.java:79)
at com.sun.tools.hat.Main.main(Main.java:143)

The smallest heap dump that I have is 400M, and it produced this error. Not so cool, really. What to do - run jmap on the jhat process?

I tried doing what I've done in the past when running into an OutOfMemoryError - reset the JVM's max heap size. The documentation says you can pass flags to the JVM running jhat by using "-J". Almost as if they knew you'd need it, they give the example of passing in the max heap size as 512MB with "-J-Xmx512m". So I tried using "-J-Xmx1024m", and the process continued further, but failed in the end:

me@me:~/heaps$ ~/jdk1.6.0_10/bin/jhat -J-Xmx1024m java_pid403M.hprof
Reading from java_pid403M.hprof...
Dump file created Sun Oct 18 10:17:15 PST 2009
Snapshot read, resolving...
Resolving 8502679 objects...
Chasing references, expect 1700 dots....................
[ a whole lot more dots, but not 1700, and then ]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Hashtable.rehash(Hashtable.java:356)
at java.util.Hashtable.put(Hashtable.java:412)
at com.sun.tools.hat.internal.model.Snapshot.addHeapObject(Snapshot.java:153)
at com.sun.tools.hat.internal.parser.HprofReader.readInstance(HprofReader.java:728)
at com.sun.tools.hat.internal.parser.HprofReader.readHeapDump(HprofReader.java:474)
at com.sun.tools.hat.internal.parser.HprofReader.read(HprofReader.java:226)
at com.sun.tools.hat.internal.parser.Reader.readFile(Reader.java:79)
at com.sun.tools.hat.Main.main(Main.java:143)

Disappointing! I wonder if anyone uses jhat at all, or if it's just a nice toy for very small heap dumps.

In fact, if you search the internet for "jhat OutOfMemoryError" you will find some very interesting links to follow up on... I'd like to get jhat working, just to see what it does. But meantime, I've also stumbled across the Java performance blog, and I'll soon be trying out the Eclipse Memory Analyzer.