Using HAT on NetBeans
Author:
Petr Nejedly, NetBeans
$Revision: 1.4 $
Document History:available in CVS
Note: Some easier ways how to generate heap dump are described in
User's FAQ about OOME.
Combination of the hprof JVM profiler and
the Heap Analysis Tool
can be very helpfull for tracking memory issues. I'll try to outline several
NetBeans specific use cases in this short article.
A short generic HAT guide can be found
here
Warning: JDK 1.4 and JDK 1.4.1 contains a bug in hprof. You cannot use
these versions with HAT.
1. Tracking an unknown memory leak
Sometimes you get a report that the IDE have eaten up all the available memory
and started throwing OutOfMemoryErrors. Sometimes you, while running
with the
memory toolbar on, realize that too much heap
is consumed. In that situation you have to find the steps that raise the heap
usage and perform them under the instrumented JVM. Because reproduction of the
steps may be more complicated or the amount of work involved nontrivial,
we need to not slow down the instrumented JVM too much. In this case I use the
following command to start the NetBeans in the instrumented JVM:
runide.sh -J-Xrunhprof:heap=dump,format=b,file=nb.hprof,depth=0,doe=n -J-Dnetbeans.debug.heap=true
The instrumentation will slow the IDE down about 5 times so you should be still
able to work with it reasonably.
With such an IDE you can do the steps needed to exploit the memory leak
and when you're done, send the java process a SIGQUIT (Like when invoking
a thread dump, Ctrl+\ on unices, Ctrl-Break on Windows). Don't forget to
force several GC cycles before making a snapshot, the snapshot will contain
unreachable objects otherwise and it will only distract your focus.
The java process will show the thread dump and save the content of the memory
to the nb.hprof file. It takes a while thus I've disabled
the dump on exit (doe=n) to have a possibility of a fast yet
clean exit of the tested NetBeans. You can also make more snapshots in one session
using SIGQUIT several times. netbeans.debug.heap=true switch
disables caches (such that are believed not to cause leaks) simplifying references graph analysis.
The tax for having quite fast VM during instrumentation is "depth=0".
The hprof is able to log the methods where the memory was allocated but we're
turning this feature off.
When you have the snapshot, you can fed it to the HAT:
hat -stack=false nb.hprof
The HAT will start a webserver at
localhost:7000
where you can walk the instances and the references between them.
One of the key views is the "Instance Count" view reachable at
localhost:7000/showInstanceCounts/.
There you can look for suspicious things like too many FileObjects, DataObjects,
strange Component subclass
instances
and so on, but you'll need a bit of experience how should the normal state look like.
To help you with this, you can use a difference between two snapshots.
You can create one snapshot before you'll provoke the leak and another
one after the leak has shown. You can then start the HAT using:
hat -stack=false -baseline=nb.hprof:1 nb.hprof:2
The Instance Count view will get another column showing
the count of the newly created instances of the class.
You can then use the "N new" link to see which instances are new
and inspect who is referencing them, like
localhost:7000/newInstances/org.openide.filesystems.AbstractFileObject
to see newly created AbstractFileObject instances.
Setting up and using the memory toolbar:
To enable the memory toolbar, right click in the toolbar area
and check the "Memory" checkbox.
You'll get an additional toolbar consisting of memory indicator
and a Garbage Collect button.
The memory indicator's tooltip shows actual size of the heap and its usage.
If you click on the indicator, it will place a mark of the actual usage so you
can use it for visual comparisons.
The Garbage Collect button spawns a single System.gc().
If you want to see something closer to your working set, press the GC button
several times in a row.
|