Today i have learned about a nice approach to detecting memory leaks in the Java SE applications using the jmap and jhat (Java Heap Analysis Tool). The process to be followed is described below:
1. Run your application.
2. Run the command jps to know the process id of the J2SE application you ran.
% jps
1234 MyApp
...
3. Perform those actions in your application which you feel will cause the memory leak. You can observe the real time heap usage plot in jconsole. Launch jconsole and select your application in it to connect to.
% jconsole
4.Then run the command jmap to dump the heap.
%
jmap -dump:file=myapp.bin 1234
This will produce a heap dump in myapp.bin file with the heap profile.
4. Run the JHAT (Java Heap Analysis Tool) as follows:
%
jhat -J-mx512m heap.bin
The above command starts a small Http server at port 7000 by default.
5. Browse to http://localhost:7000 and you will have you the heap browser - a hyperlinked set of pages from where you can trace every object allocated and who all reference the object at the point at which the heap dump was created.
6. The important pages to browse to are:
http://localhost:7000/histo/ - to see the histogram of heap usage.
http://localhost:7000/showInstanceCounts or http://localhost:7000/showInstanceCounts/includePlatform/ to see biggest types with most object allocations (ie instances).
and some advanced features of using SQL to query values of instance members:
http://localhost:7000/oql/
7. So browse to http://localhost:7000/showInstanceCounts/. Investigate "Instances" and not "Classes". Use “Reference Chains from Rootset” (Exclude weak refs!!!) to see who’s holding the instance. This tip i found in one of the links below in the reference section and it really was what was required to find the memory leaking code.
Some good references are:
- Memory leaks in Java program
- Using Mustang's jmap/jhat to profile Glassfish
- Finding Memory leaks in Java Program