Over a million developers have joined DZone.

Analyzing Memory Leaks from Dump Files with SciTech .NET Memory Profiler

·

I had to analyze a memory leak the other day and all I was provided by the customer was a couple of dump files from two points in the application’s lifetime—one dump immediately after initialization, and another dump after the memory leak has accumulated. This is an ideal scenario: now “all it takes” is to compare the two dumps and see which objects are “growing” in memory. That’s, of course, if the leak is actually in managed objects—which isn’t always the case (and VMMap is your friend here).

Naturally, analyzing memory leaks is not always easy, and even if you have a couple of dumps you can spend a very long time in a dark room with WinDbg and SOS and still have no idea where the leak is coming from. Two things that could help immensely with diagnosing memory leaks in complex heap dumps are:

Dominator set analysis—instead of focusing on the myriads of objects occupying memory and trying to figure out the retention chain of each object, dominator set analysis tries to find the objects directly responsible for keeping a large number of other objects alive1. (The Eclipse Memory Analyzer Tool can find dominator sets for large Java heap dumps.)

Visualizing heap dumps—until not long ago, the state of the art in .NET memory dump analysis was running a bunch of WinDbg commands, sometimes assisted by CLR Profiler’s poor visualization features and individual-object-level commands like !vcgroot. Naturally, there are profilers that can visualize snapshots from a live application’s heap; but doing the same for a memory dump is usually impossible.

SciTech’s .NET Memory Profiler can do both. It can import memory dumps as if they were live heap snapshots taken by the profiler, and it can perform dominator set analysis to display the number of objects retained uniquely by another object2.

Full disclosure: I was given a license for the Professional version of the .NET Memory Profiler (v4.0). Nonetheless—and you know this—the following is an unbiased walkthrough through one of the product features.

First things first: we open the Memory Profiler and choose File | Import memory dump. This takes a while—I suspect that the profiler is converting the dump to an internal representation used in the standard snapshots.

image

We do the same for any additional dumps. Generally, the import process should be linear in the number of objects in the heap dump. When the analysis completes, we can choose the snapshots to compare:

imageimage

(Naturally, I am not using customer-provided dumps here to prevent information disclosure. Instead, these dumps are taken from a memory leak analysis exercise in the .NET Debugging course.)

Now begins the fun, which I can only describe in a few screenshots and leave the rest to the profiler’s documentation and tutorials. The first thing you’ll see is a list of “issues”—and in this case, I’ve got some instances directly rooted by an EventHandler, and some other instances indirectly rooted by an EventHandler. While this isn’t necessarily a memory leak, it’s certainly suspicious and worth further analysis.

image
(click the image to enlarge it)

After clicking on MainForm.FileInformation, I get the root paths and an instance list for the suspicious objects. Here’s the root path:

image
(click the image to enlarge it)

…and here’s the instance table—for each object, the “Held bytes” column is the object’s dominated set’s size:

image

We see easily that there is a single root path for a large number of instances by clicking the type name. Alternatively, we could focus on the root itself and visualize the graph stemming from it:

image

To summarize, by allowing to import memory dumps and providing easy visualization, multiple root path traversal, instance- and type-level information, and dominated-set analysis – SciTech Memory Profiler has already helped me pinpoint a real memory leak (in the less than 24 hours since I got the license :-)).

The example above only scratches the surface of what modern profilers can do for you. If you are one of the hardcore pros still using !gcroot and !dumpheap for all your leak analysis needs, that’s great—but if you want to save time and have a tool detect some of the common issues automatically, use a profiler first.

I have been recently posting short updates and links on Twitter as well as on this blog. You can follow me: @goldshtn

 


[1] To formalize: for each heap object X there is a (possibly empty) set of roots {R1, …, Rn} keeping the object alive, i.e. each Ri is a root and there is a reference path from Ri to X. Then, we can define {D1, …, Dn} the dominator set of X where Di is the object closest to X on the reference path from Ri to X such that if Di were removed from the reference path, there would no longer be a path from Ri to X.

[2] I.e., for an object D it can find the dominated set {X1, …, Xm} such that D is in the dominator set of each Xi.

Topics:

Published at DZone with permission of Sasha Goldshtein, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}