MSDN features an article covering reasons why and how managed applications can suffer from memory leaks, how you can find them and get rid of them:
Despite what a lot of people believe, it’s easy to introduce memory and resources leaks in .NET applications. The Garbage Collector, or GC for close friends, is not a magician who would completely relieve you from taking care of your memory and resources consumption.
I’ll explain in this article why memory leaks exist in .NET and how to avoid them. Don’t worry, I won’t focus here on the inner workings of the garbage collector and other advanced characteristics of memory and resources management in .NET.
It’s important to understand leaks and how to avoid them, especially since they are not the kind of things that is easy to detect automatically. Unit tests won’t help here. And when your application crashes in production, you’ll be in a rush looking for solutions. So, relax and take the time to learn more about this subject before it’s too late.
Table of Content
- Leaks? Resources? What do you mean?
- How to detect leaks and find the leaking resources
- Common memory leak causes
- Common memory leaks causes demonstrated
- How to avoid leaks
How to avoid leaks
Now that you know more about leaks and how then can happen, I’d like to stress a few points and give you some tips.
Let’s first discuss about a general rule. Usually, an object that creates another object is responsible for disposing it. Of course, this is not the case if the creator is a factory.
The reverse: an object that receives a reference to another object is not responsible for disposing it.
In fact, this really depends on the situation. In any case, what’s important to keep in mind is who owns an object.
Second rule: Each += is a potential enemy!
Given my own experience, I’d say that events are the main source of leaks in .NET. They deserve double- and even triple-checks. Each time you add a subscription to an event in your code, you should worry about the consequences and ask yourself whether you need to add a -= to unsubscribe from the event. If you have to, do it immediately before you forget about it. Often, you’ll do that in a Dispose method.
Having listener objects unsubscribe from the events they subscribe to is usually the recommended way to ensure they can be collected. However, when you absolutely know that an observed object wont publish notifications anymore and you wish that its subscribers can be released, you can force the removal of all the subscriptions to the observed object. I have a code sample on my blog that shows how to do this.
A quick tip now. Often, issues start to appear when object references are shared among several objects. This happens because it may become difficult to keep track of what references what. Sometimes it’s better to clone objects in memory and have views work with the clones rather than having views and model objects intertwined.
Finally, even if it’s a well-known best practice in .NET, I’d like to stress one more time the importance of calling Dispose. Each time you allocate a resource, make sure you call Dispose or encapsulate the use of the resource in a using block. If you don’t do this all the time, you can quickly end up with leaking resources – most of the time unmanaged resources.
Read the whole article at How to detect and avoid memory and resources leaks in .NET applications.