Monday, November 9, 2009

Opps! A Leak! In .NET!!

Are you a smart, happy, hard-working C guy?

If yes then, well ..  you probably want to skip this post.
Do you use .NET? Are you aware of the magician called GarbageCollector? Do you like it? Because I do!

Past -- Rewinding a little ... <<<
In the times before dawn, every-day programmers needed to do a lot of work to manage their application's memroy. My hero C guy -I used to be a hero too by the way- was forced to keep track of every malloc to free it when it's no longer needed.

Now -- Fastforwarding ... >>>
Everyone (Well, almost everyone) uses a lanaguage that supports automatic memory management tools. For me as a .NET guy, I use C# and I'm very happy with what the GarbageCollector does for me (I think most .NET guys are). However, unlike everyone (again almost) else thinks, it's trivially easy to introduce memory leaks in .NET.

First let's ask Wikipedia, What is Memory Leak?  Let me quote the answer here.

A memory leak or leakage in computer science is a particular type of memory consumption by a computer program where the program is unable to release memory it has acquired

I used to think that as long as I don't use unmanaged resources (explicitly) I'm safe. The GC will free all the managed objects from memory once I'm done using them (or when there is no references to these objects). Guess what? I was mistaken!!

One more point from this Wikipedia article:
Languages that provide automatic memory management, like Java, C#, VB.NET or LISP, are not immune to memory leaks. For example, a program could create a circular loop of object references which the memory manager is unable to recognize as unreachable.

GC frees only objects that has become unreachable. If the object is still reachable, somehow (probably your mistake), then GC will not free it. Which introduces a leak ...

To be honest, with nowadays super computers, usually leaks are not a problem unless your app is really big, and runs continously for a really long period of time; this is when those tiny drops can fill the cup.

What causes those leaks?
There are quite a few reasons why a .NET app migh leak memory. The main reasons are:
1- Static References
2- Event With Missing Unsubscribtion
3- Dispose method not invoked.

In this post, I will talk about the most famouse one (the one that got me bitten): Events.
Yes, people always remember to subscribe to events, but few unsubscribe from their events.

What happens when an observer subscribes to a publisher's event is that the publisher maintains a reference to the observer in order to call the event handler on that observer. This means that unsubscribtion from events is required to delete this reference. And that is what got me bitten hard!

So, how to detect memroy leaks?
There are plenty of tools that can help you track your application progress and take snapshots and analyze the memory status of your application. Here's a list of some of those tools:
  1. JetBrains dotTrace
  2.  .NET Memory Profiler
  3. ANTS Profiler
And many others ...

I will post about other types of memroy leaks in .Net in the coming posts. So stay tuned!

No comments: