It’s a myth that managed code does not suffer from memory leaks. Managed code is as capable of springing leaks as unmanaged, though fortunately, the leaks themselves are not nearly so pernicious. In managed code, leaks are not the result of forgetting to deallocate memory – the Garbage Collector is pretty much infallible in that respect. Rather, the leaks are almost always the result of an object subscribing to an event on another object with a longer lifetime. This results in the longer-lived Grandpa object grasping so tightly to the reference to the shorter-lived object (so that it can notify it of events) that the Garbage Collector dare not clean up the whippersnapper.
Such situations can easily be detected using one of the many memory profilers around (I’ve used, and can heartily recommend JetBrains dotTrace; I’ve also heard good things about the new version of RedGate’s Ants Profiler). These help you identify the objects that you expected to be cleaned up, and then let you trace back to find the villains that are keeping them alive.
But once you’ve identified the source of the problem, what do you do? Sometimes it’s as easy as remembering to make the short-lived objects unsubscribe from the longer-lived – you can do this if the class implements IDisposable, for instance. Other times, there’s no suitable or natural point at which to do the clean-up. What then?
That’s the subject of the excellent Code-Project article Weak Events in C# which explains the problem in more detail and covers the whole range of possible solutions to the problem. Don’t let the title put you off: the solutions don’t compromise on the power of your events – you can still declare
public event EventHandler<EventArgs> CountdownToArmagedonStarted
if you want to. Rather, the title refers to the common ingredient in all the solutions, the magical WeakReference class.
Go read the article. It will be the best spent fifteen minutes of your day.