CLR Profiler is a free Microsoft tool for diagnosing memory-related performance problems in managed applications. In this post, I’m using CLR Profiler v4.0, which you can download here.
I talked about CLR Profiler here as a post-mortem diagnostic tool that can open log files generated by SOS.dll’s !TraverseHeap command and present a reference graph of all live objects. This in itself is a little-known feature of CLR Profiler; it is even less known that CLR Profiler can generate these reference graphs live, and compare them automatically to show you where a memory leak is coming from.
All you need to do is run your application under CLR Profiler, and click the “Show heap now” button periodically. This is similar to the “Take snapshot” functionality in ANTS Memory Profiler and other tools. When the application terminates, you click the “Heap Graph” button in the Summary view.
This produces a reference graph in which you can see the differences between snapshots. This is the end of the graph, which makes it evident that almost all the retained objects are strings, held by string arrays and FileInformation objects:
And this is the beginning of the graph, which makes it clear (with some experience deciphering root reference chains) that the majority of objects are retained by a static EventHandler:
If you zoom into the snapshots, you’ll see three colors, indicating the amount of memory allocated and retained between the snapshots. For example, the darkest pink objects were created between the second and the third snapshots.
There are several advanced options available for further exploration. For example, you can view only new objects and then see who allocated them (which call stack in your program is responsible for creating them). You could even look at a GC timeline and see which objects were alive at every point in time, as well as who allocated them:
To summarize, CLR Profiler still has plenty of hidden gems and you should consider using it—especially in simple scenarios. After all, it’s hard to beat its price :-)