February 24, 2005

More memory weirdness with Windows Forms

Today we were investigating several cases of Omea forms not getting released properly after closing. Usually this is not too much noticeable, but in the case of Manage Newsgroups window (which loads in memory the complete list of newsgroups on the selected server) the memory loss was measured in megabytes.

After some investigation with Reflector and .NET Memory Profiler, we found that the leaks were caused by two issues in the Windows Forms implementation. One is clearly a bug, and another may be a bug or some kind of a weird compatibility fix.

The first issue is simple. When you attach an ImageList to a ListView, the ListView hooks two events of the ImageList: RecreateHandle and Disposed. However, ListView.Dispose() unhooks only the Disposed event handler. In Omea, there is a global image list of all resource icons that exists all the time while Omea is running, and the ListView on the form remained forever live because of the event handler attached to the global image list. The form remained live because of an event handler attached to ListView.

Fortunately, there is an easy workaround for this: we can just clear all ImageLists on a ListView when the form is disposed.

The second issue is more complex: because of an implementation weirdness in Form.RemoveOwnedForm(), the last shown modal dialog remains in the owned forms list. (It is not visible through Form.OwnedForms property. The list is stored as two items in the property store: the count and the array of forms. The size of the array returned from OwnedForms is determined by the count. When the last form is removed, the count is decremented to zero, but the corresponding item in the array is not reset to null.)

For this one, we weren’t able to find a good workaround. Sure, we could use some heavy reflection hackery to dig into the Form internals and clear the owned forms array manually, but this is very likely to break on other versions of the framework besides 1.1. Because of this, and since only the last shown modal dialog remains forever live, we decided that we could live with the second problem for now.

The fix for the first problem will be integrated in Omea 1.0.4.

Posted by Dmitry Jemerov at February 24, 2005 12:40 AM | TrackBack
Post a comment

Remember personal info?