I was recently tracking memory leak in one of our applicatios, however the problem was only occuring in our production environment and the network latency between production subnet and my local subnet was too high to run profiler (I tried). So, I had to use some other tools to look at the snapshot of memory that was in use. I found jmap and jhat that are shipped with JDK (1.6 in our case) pretty handy. When memory usage was high, I dumped the memory using jmap, e.g.
jmap -F -dump:file=/tmp/dump.out
I then copied the file to my local machine and ran jhat using
jhat dump.out
Though, jhat is fairly slow, but it finally starts the web server on port 7000 and you can then point your browser to
http://mymachine:7000
The jhat can also read data from hprof that you can dump by adding following vm option:
-agentlib:hprof=heap=sites
and then read the file using jhat. In addition to above tool, you can run garbage collection in verbose mode using following vm option:
-verbose:gc -verbose:class -Xloggc:gc.out -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
Finally, you can use jconsole to look at memory graph by adding support of jmx to your application server, .e.g.
-Dcom.sun.management.jmxremote.port=9003 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote
Despite all these options, I find profiler is much better for finding memory leaks, but these tools helped a bit.