Archive for April, 2010

ImageList and .NET leaks

Wednesday, April 14th, 2010

Even with garbage-collected managed memory systems like those found in C#/.NET applications still suffer from leaks.

Most of the time, the “leak” is an object that has a reference to it being held by a static object. These can be a pain to identify, and near impossible in a large application without the aid of additional memory tracking tools. SciTech’s .NET Memory Profiler software is such a tool, and has proven itself invaluable in detecting these problems.

It surprises me how often leaks come back to (mis)use of the innocent looking ImageList object. For example, I have an ImageList object that contains a set of icons for different document types, and use it for ListViews, TreeViews, and anywhere else in the UI where I’m presenting collections of documents. It’s all too easy to set the image list:

myListView.SmallImageList = MyApp.DocumentIcons;

…then assume that when this particular UI goes away, all the contents go away too.

Under the surface, pointing a ListView control at an ImageList also causes the ImageList to store a reference back to the ListView. This way, if an icon is modified in the ImageList, all the ListViews and other controls that are using it can be updated too. The downside is when you forget to reset the SmallImageList property in the ListView control when the control containing the ListView is being disposed. Because the ImageList refers to the ListView, the ListView won’t go away. The ListView refers to the parent UI, the parent UI refers to the document, the document refers to the data, and so on. So when we set our document reference to null, while we might expect the whole lot to be disposed, they continue to persist in memory,  accessible only through the ImageList object.

SciTech’s tool allows me to take snapshots before and after opening and closing a document or particular UI, and compare them to see what objects have been created but not freed. I’ve been using it for a few days and have already found a couple of commonly used UserControls in a UI-heavy application that weren’t being disposed of correctly.