How do you find memory leaks using the Netbeans profiler?
There are several resources on the web that can give you a hand
http://www.javapassion.com/handsonlabs/nbprofilermemory/
http://www.netbeans.org/kb/articles/nb-profiler-uncoveringleaks_pt1.html
http://kirk.blog-city.com/more_on_memory_leaks.htm
In a nutshell, you monitor the "surviving generators", objects that are kept in the memory by your application.
When you see that this metric gets out of hand, you can switch to the Memory Live profiling mode, sort the classes by surviving generators and then with the right click mouse button select the "Show Allocation Stack Traces" option
Setup
Since some of the links here are a little out of date and targeted at NetBeans 6.0, the following is a little update for plugging memory leaks in Java desktop applications using Netbeans 6.8.
To begin, you need to perform a wide search of your application to find what general areas/features that might be leaking memory. So start up the NetBeans profiler by selecting:
Profile -> Profile Project(project name)
Then setup your profiler as follows:
Wide Search
So you can see when you leak memory and to help guide your search, bring up the telemetry overview (Marked as A in the picture below).
When doing wide searches, you want to keep running a bunch of steps that takes your application on a round trip from doing something, back to the originating "clean" state. In my case, I pretty much inserted some data into my application (file->open), displayed it (show) and then cleared it all (file->new). After I had done file->new I was expecting the used heap and number of surviving generations to be the same as when I started... If they are still high after the garbage collector has run, you have leaked a bit of memory.
Narrowing the Search
Now that you have found a feature in your application that leaks memory, it is time to narrow the search and figure out exactly what objects are still being referenced. This is done in the NetBeans profiler by taking "heap dumps":
Profile -> Take Heap Dump...
This will bring up the heap on a summary page, switch to the classes view and filter for your projects classes by entering the root package name i.e: org.yourproject, sort by Instances [%] and you will have the objects that are consuming the most memory:
Now, run the round trip steps you found to be leaking during the wide search and take another heap dump:
Profile -> Take Heap Dump...
By comparing the two lists, look for classes that have more instances in the second dump than in the first. Classes with more instances could be the ones leaking memory. In the second dump file, double click the class that could be the one leaking to bring it up in the instances view:
Down the left are all the instances of the particular class you double clicked on and if you select one, its fields and references will be populated in the right. Since we suspect this object might be leaking, something must still be holding a reference to it. Right click on "this" in the reference list and select "Show Nearest GC Root". If a dialog comes back with "No GC root found", that means the Java Virtual Machine will garbage collect it next time round and the object is not responsible for the leaking memory. If however, the tree expands then this could be one of the leaky culprits.
The key to this step, is to work from the top of the list down. In the image above, IntDataValue is the object we think is leaking, and the next thing down in the tree is the object that is referencing it. Field is the variable that is holding the reference, and type is the type of object that is holding it. When working your way down the list keep flicking to the source code and ask yourself the following:
Why is this holding a reference?
Should it be holding a reference?
While walking down the tree, asking myself these questions I often find that running the debugger and stepping through code, is the only way to find the answers.
UPDATE: Assisting with narrowing the search
Above is the original mechanisim I was using to narrow the search, but I have found another way to help narrow the search by using the "Compre memory snapshot..." feature in the "Profile" menu. First take a snapshot (see screenshot).
Now, run the round trip steps you found to be leaking during the wide search and take another snapshot. Save them somewhere you can find them using the Save As... button.
Select Profile -> Compare Memory Snapshot...
Select the two snapshots, being careful to put the first snapshot in the top slot, and the second snapshot in the bottom slot (otherwise you will get incorrect negative memory changes):
This will generate a screen similar to the following, where the number of bytes is size of change in allocations between the two snapshots (i.e. large growths might be suspect memory leaks, along with the change in the number of allocations):