Although the .NET Framework takes the memory management task out of your hands, there are still a few things that you must pay attention to when disposing of an object in order for the Garbage Collector to do its work properly.

You would think that once you remove the reference from an object it will eventually be collected by the Garbage Collector, that’s almost true. The fact is that, if that object was registered to an event published by another object, it won’t be collected by the Garbage Collector.

Why you ask? Allow me to explain.

When you register to an event you provide a delegate, and that in fact acts as a reference from the object that published the event to the registering object. So in order to make the GC collect the registering object, you must unsubscribe from all the events. Otherwise there is still a reference to that object in the form of that delegate.

To sum things up, the safest way to ensure that an object will be collected by the GC is to make it inherit IDisposable and in the Dispose method unsubscribe from all the events you were subscribed to.

Subscribe to our feed and get the complete code sample for this article

Amit

Tags :

18 Responses to “A .NET memory leak you did not think about”


  1. Chris Carter

    Said on March 17, 2008 :

    Please post something tangible that shows how you came to this conclusion. What tool did you use to determine what was left in memory?

  2. Damien Guard

    Said on March 17, 2008 :

    This is a known problem with this pattern and GC based systems under the name lapsed listeners.

    You can’t always remove from the event mechanism if the objects are managed elsewhere and it doesn’t provide a facility to do so – e.g. TreeView control.

    Thankfully .NET 3.5 has a WeakEventManager class that can provide event services without this problem by keeping weak references to the listeners.

    [)amien

  3. Jason Kealey

    Said on March 17, 2008 :

    I ran into this very same issue last week.

    Here’s how I discovered the source of the issue:
    http://blog.lavablast.com/post/2008/03/How-I-lost-my-WinDbg-virginity.aspx

  4. Razan Paul

    Said on March 17, 2008 :

    It sounds bad.It is not a memory leak problem.
    Don’t waste other’s time.

  5. rekna

    Said on March 17, 2008 :

    Can you give a small code example?

  6. Admin

    Said on March 17, 2008 :

    To Razan

    Of course it is a memory leak you think you have disposed of an object but infact you didnt

    and if this object takes alot of memory you are in a jam

  7. Admin

    Said on March 17, 2008 :

    To Chris

    You dont need a tool or anything you can just see that in debug mode the “Disposed Object” keeps getting event, and therefore still lives

    I will post some code to demonstrate the matter.

    Amit

  8. JV

    Said on March 17, 2008 :

    I agree with Razan that it isn’t a memory leak problem. A memory leak is caused by something which is still active in memory, but already should have been gone. Well, this is not the case here, because there still is a valid reference available. So no problem here, just something tricky which you should keep in mind.

  9. Admin

    Said on March 17, 2008 :

    But this is exactly what that is, an object in the memory YOU thought you released, but in fact you did not, the object will keep on responding to events and make you application do unexpected things and of course keep holding resources. too many object like this and you will run out of memory, that is exactly what a memory leak is

    Amit

  10. Admin

    Said on March 17, 2008 :

    I have added an exmaple project to illustrate it

  11. FellowBlogger

    Said on March 17, 2008 :

    Terrific article! FYI, it is a violation of Google AdSense Terms of Service to place images next to your Google ads. If Google reviews your site, they may ban you from AdSense. This happened to a friend of mine, and it took him two months to restore his Google AdSense, so be warned!

  12. Jeme

    Said on October 5, 2009 :

    I Agree with people that doesn’t consider this a memory leak as well…

    This is in no way different than any other references between objects, it is just a bit counter intuitive if you don’t know the way it works…

    If you think about this as a Observer subscribing to an Observable, it is in fact just the same, just as the Observer has to un-subscribe it self from the Observable to be able to be collected, for events you have to do the same thing.

    And in both situations if both the Observer and Observable is released, the GC will eventually take care of both, and that’s the exact same thing with events.

    This is by design and not a flaw. Or at least I hope it is, because if a subscriber is actually meant to die if all non-event related hooks are released, then it could just cause many other horrific bugs…

    Evaluate:

    static MyRaiser obj = new MyRaiser();

    void Init()
    {
    obj.OnEvent += new MyHandler().OnEventMethod;
    }

    For the case above, the lifetime for the Host (obj) and the handler
    is tied together, this would otherwise not be possible to do by your point of view since the “MyHandler” would die straight away.

    MyHandler dies eventually when:
    void Release()
    {
    obj = null;
    }

  13. bet angel

    Said on February 16, 2014 :

    Thanks for finally writing about >A .NET MEMORY LEAK YOU DID NOT THINK ABOUT | Dev102.com <Liked it!

5 Trackback(s)

  1. Mar 17, 2008: Wöchentliche Rundablage: ASP.NET MVC, Silverlight 2, LINQ… | Code-Inside Blog
  2. Mar 18, 2008: Finds of The Week - March 16, 2008 » Chinh Do
  3. Mar 26, 2008: A New Pattern for Event Declaration | Dev102.com
  4. May 30, 2008: HOW TO FIND MEMORY LEAKS WITH CLRPROFILER | Dev102.com
  5. Mar 14, 2009: Measure String Size In Pixels (C#) | Dev102.com

Post a Comment