Collecting event handler / delegate garbage

The .NET's garbage collector (GC) is a wonderful thing: you simply instantiate objects and when they're out of scope and / or no reference is known to those instances, they get cleaned up and you don't have to worry.

At least... in most cases. There are situations where you might think the objects you left behind get cleaned up but instead are kept in memory because there is still a reference known to those objects so the GC will not clean them up. In other words: the objects can't be 'marked for garbage collection'. When is this? Well, if you wire an event handler in class A to an event of class B and A gets out of scope. You might think: "A is out of scope, it gets cleaned up.", but that's not true. The event of B which is wired to a method (via a delegate) of A is in fact still referencing A and therefor A will be kept in memory via the delegate added to the event of B.

So, as a rule of thumb, always de-wire event handlers when you want the object which contains the event handler to go out of scope (and the object which holds the event does not) and to get cleaned up by the GC. Most of the time you'll need this in windows forms, where you'll wire an event handler in the form class to a given object which will eventually fire events which will have some effect on the form's contents. When you close the form and the object wired to the event handlers stays alive in another part of the application, the form is still in memory and will not be garbage collected due to the dangling event handler delegate. Add event handler cleanup code to the form closing event handlers to clean this up.

Of course a form itself doesn't have to do this with event handlers wired to events of its own controls. The reason why is left as an exercise to the reader ;) :)

No Comments