Tuesday, January 27, 2009

Memory Leaks

I've been having tons of fun lately tracking down memory leaks in our application. Some of them were known, others unknown. I've been doing better than I expected to do, using only two tools:

ProcessExplorer, which is registered as my default Task Manager
and
ClrProfiler, which even though it's for .Net 2.0 works just fine on my .Net 3.5 app.

I'll load our app (from a Release build), and perform a known set of actions. The memory profile looks like so:



I expect there to be some accumulation of memory, but not this much!

Even just examining a simple heap dump from the ClrProfiler can be illuminating:



The ZipPackage shown above is a temporary package that got added to the PackageStore but was never removed. That qualifies as a leak!

I went through an iterative process of identifying these lingering items and cleaning them up, and now my memory profile for the exact same sequence of steps looks like this:



The same general shape and characteristic curve is there, but you'll notice that the overall allocated memory has been cut in half: 141.3 MB as opposed to the original 315.2 MB. The slope of this profile, while still increasing, is much less steep than it was originally. For the test I ran, I can't expect all of the memory to go away. I'm still going to be holding onto a few things. But the fewer things I hold onto, and the smaller they are, the better off our application will be!

It's unfortunate that our process didn't prevent these leaks from entering into the code and even more unfortunate that our project timeline didn't allow for their extermination before now. But on the bright side, it's getting taken care of, and I'm honing my skills.