In previous blog posts, I have covered using VisualVM to acquire HotSpot JVM runtime information in a manner similar to jinfo and how to use VisualVM in conjunction with JMX and MBeans in a manner similar to JConsole. This blog posting looks at how VisualVM can be used to generate and analyze a heap dump in a manner similar to that done with command-line tools jmap and jhat.
The jmap (Java Memory Map) tool is one of several ways that a Java heap dump can be generated. The Java Heap Analysis Tool (jhat) TechNotes/man page lists four methods for generating a heap dump that can be analyzed by jhat. The four listed methods for generating a heap dump are the use of
jmap, JConsole (Java Monitoring and Management Console), HPROF, and when an OutOfMemoryError occurs when the
-XX:+HeapDumpOnOutOfMemoryError VM option has been specified. A fifth approach that is not listed, but is easy to use, is Java VisualVM. (By the way, another method is use of the MXBean called HotSpotDiagnosticMXBean and its dumpHeap(String,Boolean) method.)
jmap tool is simple to use from the command line to produce a heap dump. It can be used against a running Java process whose piocess ID (pid) is known (available via jps) or against a core file. In this post, I'll focus on using
jmap with a running process's ID.
The jmap page states that
jmap is an experimental tool with relatively limited capabilities on Windows that may not be available with future versions of the JDK. This page also lists options available to specify how
jmap should generate a heap dump.
The following screen snapshot shows how
jmap can be used to dump a heap.
The generated dump file,
dustin.bin in this case, is binary as shown in the next screen snapshot.
The binary heap dump can be read with the
jhat tool. Sun's Java SE 6 included implementation of
jhat replaces HAT, which was formerly available as a separate download. It is almost trivial to run
jhat. One need only invoke
jhat on the heap dump file generated with
jmap (or alternative dump generation technique) as shown in the next screen snapshot.
With the heap dump generated (
jmap) and the
jhat tool invoked, the dump can be analyzed with a web browser. The output on the console tells us that the dump is available on port 7000 (this default port can be overridden with the
-port option). When I run the browser on the same machine on which I ran
jhat, I can use
localhost for the host portion of the URL. The starting page using localhost and port 7000 is shown in the next screen snapshot.
Arbitrary Object Query Language (OQL) statements can be written to find necessary details in the heap dump. The
jhat-started web server includes OQL help at the URL http://localhost:7000/oqlhelp/. See also Querying Java Heap with OQL for more details on how to use OQL. However, one can often find what one needs simply using the already provided information and moving between pieces of information using the provided hyperlinks.
The following screen snapshot demonstrates one of the more useful pages available thanks to
jhat's web server-based output of the heap dump. This page shows the number of instances of various Java objects, including platform objects.
A significant aid in understanding what these web pages generated by
jhat mean is the VM Specification on Class File Format. In Section 4.3.2 ("Field Descriptors") of this document, there is a table that shows the mapping of field descriptor characters to the data type we use. According to this table, "B" indicates a
byte, "C" indicates a
char, "D" indicates a
double, "F" indicates a
float, "I" indicates an
integer, "J" indicates a
long, "L<someClassName>" indicates a reference (instance of a class), "Z" indicates a
[ indicates an array.
So far, I have looked at using
jhat from the command-line to generate a heap dump and provide a web browser-based method for analyzing the generated heap dump. Although these tools are relatively easy to use, VisualVM provides similar functionality in an even easier approach.
One method for generating a heap dump in Visual VM is to simply right click on the desired process and select "Heap Dump". This method is shown in the next screen snapshot.
This generates the heap dump as indicated by its name underneath the Java process.
A second approach for generating a heap dump with VisualVM is to click on the Java process of interest so that relevant tabs ("Overview", "Monitor", "Threads", and "Profiler") come up in VisualVM. Selecting the "Monitor" tab provides the "Heap Dump" button as shown in the next screen snapshot.
Clicking on the "Heap Dump" button leads to a heap dump being generated just as it was with the right click option described above. This is shown in the next screen snapshot, which happens in this case to show the "Summary" tab of the analyzed heap dump.
In addition to the "Summary" tab of the heap dump analysis, other interesting details from the heap dump are presented in the "Class" tab. This tab includes horizontal bar charts that graphically indicate the percentage of total instances that are associated with each class. An example is shown in the next screen snapshot.
The displayed classes are spelled out rather than using symbols like those described above for
jhat-based heap dump analysis. One can right-click on any class in the "Classes" tab and select "Show in Instances View" to see details on each individual instance of the selected class. This is shown in the next screen snapshot.
VisualVM provides several advantages when creating and analyzing heap dumps. First, everything from creation to analysis is in one place. Second, the data is provided in what may be considered a more presentable format with graphical support. Finally, other tools can also be used in VisualVM in conjunction with the heap dump analysis. VisualVM provides one-stop shopping for many of the development, debugging, and performance analysis needs of the Java developer.