Circular References, Memory Leaks, and other Baddies
In a garbage collected environment such as .NET, it is possible to unwittingly leave objects in a state where the garbage man will be "on vacation". One way to check on this kind of stuff is with profiling products such as the Scitech .NET Memory Profiler: http://www.scitech.se/memprofiler/
Ian Griffiths has a well - written, concise piece on this subject here: http://www.interact-sw.co.uk/iangblog/2004/07/07/circulareventrefs
One of the issues we found with this is when you have a lot of controls on a UserControl or form and you unwind it, thinking you have gotten rid of everything.
Except, you may have not done so - event handler delegate calls may still hold a reference to their target. We found this to be especially noticeable on controls derived from RichTextBox - a control with a lot of Interop going on under the hood and notoriously "Buggy" to boot.
The problem is solved with a neat little method we call in the Dispose Block , "UnregisterChildControls":
private void UnRegisterChildControl(Control ctrl)
{
if (ctrl is CustomCheckBox)
{ CustomCheckBox cb = (CustomCheckBox)ctrl;
cb.CheckedChanged -= new EventHandler(cb_CheckedChanged);
}
else if (ctrl is CustomDateComboBox)
{
CustomDateComboBox cmb = (CustomDateComboBox)ctrl;
cmb.DateSelected -= new DateSelectedHandler(cmb_DateSelected);
}
}
-- By "cleaning up our room" in this manner, we've seen those scary looking memory consumption profiles flatten out very nicely. :-)
Ian Griffiths has a well - written, concise piece on this subject here: http://www.interact-sw.co.uk/iangblog/2004/07/07/circulareventrefs
One of the issues we found with this is when you have a lot of controls on a UserControl or form and you unwind it, thinking you have gotten rid of everything.
Except, you may have not done so - event handler delegate calls may still hold a reference to their target. We found this to be especially noticeable on controls derived from RichTextBox - a control with a lot of Interop going on under the hood and notoriously "Buggy" to boot.
The problem is solved with a neat little method we call in the Dispose Block , "UnregisterChildControls":
private void UnRegisterChildControl(Control ctrl)
{
if (ctrl is CustomCheckBox)
{ CustomCheckBox cb = (CustomCheckBox)ctrl;
cb.CheckedChanged -= new EventHandler(cb_CheckedChanged);
}
else if (ctrl is CustomDateComboBox)
{
CustomDateComboBox cmb = (CustomDateComboBox)ctrl;
cmb.DateSelected -= new DateSelectedHandler(cmb_DateSelected);
}
}
-- By "cleaning up our room" in this manner, we've seen those scary looking memory consumption profiles flatten out very nicely. :-)
Comments
Post a Comment