A powerful last resort against bugs that don't reveal itself in testing, through logging or through stack dumps are heap dumps.
In heap analysis we copy the entire memory of a running program and load it into an analyser. The analyser then allows us inspect the entire application state, almost as if we just hit a breakpoint with a debugger.
Performing a dump
You'll once again need the process ID of your java program to perform the dump.
We will be using the utility
jcmd (.exe under windows), which is packaged into the Java Development Kit (JDK). It is in same directory as jstack
We perform a dump by running
jcmd Process_ID GC.heap_dump dump.hprof
In this case the file ending does matter, since we will be using the Eclipse Memory Analyser which only accepts ".hprof" files.
Loading the dump
Select "File/Open Heap Dump" and navigate to your ".hprof" file. The analyser will unpack the dump and create a bunch of files surrounding it.
The feature I found most helpful was the ability to query all class instances, as if they were a MySQL database. Open the query window like so:
From here you can query your class instances by their full names, meaning the class name itself and all the packages it is contained in.
You can also click and expand any of the entries. Notice the "Inspector" window on the left. Here you can see the member variables of the currently selected instance:
Now that are tons of results, using the query language we can filter the results like so:
select * from root_package.sub_package.Class where toString(field) = 'something'
toString() method. This is needed because by default the memory analyser doesn't know the datatype, it can only infer it. By using
toString(field) we are telling it to interpret that field as a reference to a string, and return us that value.
For further information on the analyser visit the docs