locked
C# memory leaks RRS feed

  • Question

  • i guess memory leaks will be taken by .NET framework, then what is the importance of handling memory leaks in C# applications.

    Is this really required for the application? if so then why it is required & how should i take care of those things?

    Monday, March 29, 2010 7:04 AM

Answers

  • To see the telltale sign of memory leaks one fires up perfmon and looks at Private Bytes in perfmon for that telltale sign. See this article Identify And Prevent Memory Leaks In Managed Code to begin that process.

    One other item to look for is on the Processes tab of the Windows Task Manager. ( View + Select Columns,) check Handles, GDI Objects and USER Objects. Observe these values for your program. If there is t a handle leak, you'll see one of these steadily climbing if you do. GDI in all likelihood under those scenarios.

    In general when the OS runs an application it tries to determine how much memory is being used. It will allocate more memory for the application that what the application currently needs. The reason for that is, to allocate/deallocate memory is a cpu intensive operation. Why parallel what the app needs when it can reside in a pool of memory which will allow it, the app, to expand and contract with no interference from the operating system. Saves on cycles.

    What the developer sees is a high water mark for memory. If the system is not stressed, the system will not reclaim any memory and keep the high water mark. There are many posts in this forum where the users say, processing done, memory cleaned up but the OS still shows my app at memory point X, when it should be memory point M (lower). Winform users report the same but if one minimizes the app, suddenly the mem usage reported drops to that M level. That is done by design. Minimizing suggests that an app doesn't need the memory for it will not be interacting with the user and the OS will reclaim the point. If its not a winform and the OS is not stressed, the app stays at the high water mark of X.


    More articles of interest:

    CLR Inside Out: Investigating Memory Issues -- MSDN Magazine, November 2006
    Debug Leaky Apps: Identify And Prevent Memory Leaks In Managed Code -- MSDN Magazine, January 2007
    VMMap which is a process virtual and physical memory analysis utility,
    Download details: Debug Diagnostic Tool v1.1
    Joe Duffy's Weblog (Dispose, Finalization, and Resource Management)

    HTH GL
    William Wegerson (www.OmegaCoder.Com)
    • Proposed as answer by CiaranODonnell Wednesday, March 31, 2010 3:57 PM
    • Marked as answer by AdityaReddyM Thursday, April 1, 2010 4:14 AM
    Wednesday, March 31, 2010 3:20 PM
    Moderator

All replies

  • Check this KB

    http://support.microsoft.com/default.aspx/kb/318263?p=1


    Thanks,
    A.m.a.L
    Dot Net Goodies
    Don't hate the hacker, hate the code
    • Proposed as answer by CiaranODonnell Wednesday, March 31, 2010 3:57 PM
    Monday, March 29, 2010 7:22 AM
  • "memory leaks will be taken by .NET framework" -  Are you refering to Automatic Garbage collection here?

    Read about classes that implement IDisposable Interface.
    http://msdn.microsoft.com/en-us/library/system.idisposable.aspx

     

     

    Monday, March 29, 2010 12:05 PM
  • C#'s garbage collection really helps a lot, of course, but unfortunately I see a distressingly large number of leaks in production code. The main offender is the use of event handlers.

    Consider the following code snippet:

    public DemoClass(SomethingThatRaisesAnEvent eventSource)  // Constructor
    {
        _eventSource = eventSource;
        _eventSource.SomeEvent += somethingThatHandlesAnEvent;
    }
    
    public void Dispose()
    {
        _eventSource.SomeEvent -= somethingThatHandlesAnEvent;
    }
    
    private SomethingThatRaisesAnEvent _eventSource;
    

    If you fail to unsubscribe the event in the Dispose() method (i.e. remove the contents of the Dispose() method shown above), you can have a nasty resource leak. What happens is that the lifetime of the instance of DemoClass becomes bound to the lifetime of the 'eventSource' object that is passed in. This is because the somethingThatHandlesAnEvent() method can be called as long as the eventSource is alive, therefore there is a reference from the eventSource to the instance of DemoClass.

    (I remember this as simply: "the left-hand side of an event subscription keeps the right-hand side alive".)

    If you have code that creates a single SomethingThatRaisesAnEvent object at the start of the program and does not dispose/unreference it until the end of the program, then every single object of type DemoClass() that is created with it will remain in memory until the end of the program! This can be A Very Bad Thing Indeed. ;)

     

    Monday, March 29, 2010 3:05 PM
  • @Matthew Watson

    Is this a case of circular references ?


    Ramakrishna http://tastycode.blogspot.com/
    Monday, March 29, 2010 4:46 PM
  • Circular references?  No.  I agree with Matthew's observation regarding events and event handlers. 

    Let me say it differently.  Whenever a class subscribes to events from objects defined and instantiated by external classes , it really needs to unsubscribe to those events whenever that class instance is disposed. 

    This is because the external object instance has an Invocation List, IL of event handlers associated with its' event.  When the event is fired, then the methods in the IL are called. Let's call this external object the Publisher.

    Suppose this object, Publisher, is declared and instantiated in one class, Subscriber1.  This object is now passed to another class' constructor so that it, too, can subscribe to events, Subscriber2.  When you subscribe to the event, a method associated with Subscriber2 is added to the IL of event Publisher.  Let's suppose that both Subscribers are forms.

    If the Subscriber2 Form is closed, the Garbage Collector will check to see if the form instance has any 'active connections' to other objects.  The GC will not dispose of an active object.  The GC will see that the Publisher has a target method in its IL that is part of the Subscriber2 form instance. 

    So the GC does not dispose of the form. It sits in memory and memory consumption increases each time you create an instance of this form, Subscriber2.

    If it did dispose of the form instance, you would get a null reference error when the event were fired.  It would try to call a method on an object instance that no longer existed.  So, remove the target method by unsubscribing as Matthew showed.

    Rudy  =8^D


    Mark the best replies as answers. "Fooling computers since 1971."
    Monday, March 29, 2010 5:02 PM
    Moderator
  • I totally agree with Rudedog2. Even I experienced the same issue in my recent development. It was a chat application where the client will register for MessageRecieved events on server. In my server code I forgot to unregister the event. Once the client closes the connection, initially i made sure that the object is freed by assigning null. On performance testing I noticed one strange behavior like

    When the application started it was using 100 mb of memory. I connected 1000 client and the memory consumption changed from 100 to 120. I disconnected all the clients then I noticed the memory is still in 120 and is not at all getting reduced. Again I connected 1000 memory goes to 140. At that point I found there is some memory leak. I use sos to get all the live objects and find the connection object is not getting release and find I forgot to unsubscribe the event.

    What a simple mistake :-)


    Thanks,
    A.m.a.L
    Dot Net Goodies
    Don't hate the hacker, hate the code
    Monday, March 29, 2010 5:10 PM
  • In my server code I forgot to unregister the event.

    Aren't you supposed to unscribe (unregister) the event in the client code ?
    Ramakrishna http://tastycode.blogspot.com/
    Monday, March 29, 2010 5:51 PM
  •  

    If the Subscriber2 Form is closed, the Garbage Collector will check to see if the form instance has any 'active connections' to other objects.  The GC will not dispose of an active object.  The GC will see that the Publisher has a target method in its IL that is part of the Subscriber2 form instance. 

    So the GC does not dispose of the form. It sits in memory and memory consumption increases each time you create an instance of this form, Subscriber2.

     

    I see your point. Subscriber2 form can't be disposed of as publisher IL points to a subscriber2 form's method. Then, subscriber2 also has a reference to publisher in _eventSource which is what made me use the term 'circular reference'. Frankly, I really don't know when circular references get created.

    I know that for GC to free up an object, no part of the program should have any references to it. Subscriber2 holding a reference to publisher has no effect on it getting garbage collected.


    Ramakrishna http://tastycode.blogspot.com/
    Monday, March 29, 2010 6:04 PM
  • In my server code I forgot to unregister the event.

    Aren't you supposed to unscribe (unregister) the event in the client code ?
    Ramakrishna http://tastycode.blogspot.com/
    I am not worried about the client. The server has a connection object for each client. Once the client sends a message to the server, the connection object's message received event will fire. The server will process the request...

    Thanks,
    A.m.a.L
    Dot Net Goodies
    Don't hate the hacker, hate the code
    Monday, March 29, 2010 6:12 PM


  • i guess memory leaks will be taken by .NET framework, then what is the importance of handling memory leaks in C# applications.

    Is this really required for the application? if so then why it is required & how should i take care of those things?

    There can be an infinite reasons why objects do not get disposed, so I don't think there is one answer to your question.  It depends upon what the code does, and how it does it.  But, having a collection that is referencing an object that is a candidate for disposal is one an easy possibility to overlook, and perhaps one of the most mind boggling to track down if you are not aware of the possibility.

    Mark the best replies as answers. "Fooling computers since 1971."
    Monday, March 29, 2010 7:03 PM
    Moderator
  • Try to use using statement with all disposable objects. it's really great choice which do the job automatically, in a more readable code. also, search the web for ".NET Profiler". these softwares can help you to find bottlenecks in the application.
    My Blog - MSDN Complement By Providing Visual C# Walkthroughs and Sample Codes - Founded In February 24, 2010
    Monday, March 29, 2010 7:18 PM
  • I think the term 'circular references' does make sense here. I will try to explain it with an example.

    I have a class that implements some workflow consisting of n steps and at every step it raises an event.

    I have a form that is interested in some of those events and subscribes to them and as in Matthew Watson's

    example holds a reference to the publisher in eventSource field.

     

    Now when my workflow is done, it becomes a candidate for garbage collection but since eventSource in the subscriber is

    pointing to it, it can't be freed up. On the other hand, subscriber is being referenced from publisher's IL list.

    Neither one can be freed up first as it is being referenced by the other one.

    Any comments ?

     


    Ramakrishna http://tastycode.blogspot.com/
    Tuesday, March 30, 2010 12:40 AM
  • i got it for events

    Tuesday, March 30, 2010 4:19 AM
  • I think the term 'circular references' does make sense here. I will try to explain it with an example.

    I have a class that implements some workflow consisting of n steps and at every step it raises an event.

    I have a form that is interested in some of those events and subscribes to them and as in Matthew Watson's

    example holds a reference to the publisher in eventSource field.

     

    Now when my workflow is done, it becomes a candidate for garbage collection but since eventSource in the subscriber is

    pointing to it, it can't be freed up. On the other hand, subscriber is being referenced from publisher's IL list.

    Neither one can be freed up first as it is being referenced by the other one.

    Any comments ?

     


    Ramakrishna http://tastycode.blogspot.com/

    Garbage collection doesn't care about circular references. It only cares if an object can be reached via a reference on the heap. This means that circular or self-referential data constructs such as doubly-linked lists will still be garbage collected.

    In other words, you can ignore circular references for these purposes; live references from a root on the heap are all that count.

    Tuesday, March 30, 2010 8:42 AM
  • i got it for events


    Good.  Events are just an isolated case that is all too often and easily overlooked; i.e., a collection in another object containing references to the object that you wish to dispose. As long as that reference is there, the object cannot be disposed.  The reference needs to be removed.

    These scenarios with events can be true of any collection, as A.M.A.L. cited in his example.

    Rudy  =8^D


    Mark the best replies as answers. "Fooling computers since 1971."
    Tuesday, March 30, 2010 12:43 PM
    Moderator
  • Do we have any list of "Good-To-Do" things to minimize the memeory leaks?
    Wednesday, March 31, 2010 11:46 AM
  • Won't you like to search the web for ".NET Profiler"?. these softwares can help you to find bottlenecks in the application.


    My Blog - MSDN Complement By Providing Visual C# Walkthroughs and Sample Codes - Founded In February 24, 2010
    Wednesday, March 31, 2010 3:08 PM
  • To see the telltale sign of memory leaks one fires up perfmon and looks at Private Bytes in perfmon for that telltale sign. See this article Identify And Prevent Memory Leaks In Managed Code to begin that process.

    One other item to look for is on the Processes tab of the Windows Task Manager. ( View + Select Columns,) check Handles, GDI Objects and USER Objects. Observe these values for your program. If there is t a handle leak, you'll see one of these steadily climbing if you do. GDI in all likelihood under those scenarios.

    In general when the OS runs an application it tries to determine how much memory is being used. It will allocate more memory for the application that what the application currently needs. The reason for that is, to allocate/deallocate memory is a cpu intensive operation. Why parallel what the app needs when it can reside in a pool of memory which will allow it, the app, to expand and contract with no interference from the operating system. Saves on cycles.

    What the developer sees is a high water mark for memory. If the system is not stressed, the system will not reclaim any memory and keep the high water mark. There are many posts in this forum where the users say, processing done, memory cleaned up but the OS still shows my app at memory point X, when it should be memory point M (lower). Winform users report the same but if one minimizes the app, suddenly the mem usage reported drops to that M level. That is done by design. Minimizing suggests that an app doesn't need the memory for it will not be interacting with the user and the OS will reclaim the point. If its not a winform and the OS is not stressed, the app stays at the high water mark of X.


    More articles of interest:

    CLR Inside Out: Investigating Memory Issues -- MSDN Magazine, November 2006
    Debug Leaky Apps: Identify And Prevent Memory Leaks In Managed Code -- MSDN Magazine, January 2007
    VMMap which is a process virtual and physical memory analysis utility,
    Download details: Debug Diagnostic Tool v1.1
    Joe Duffy's Weblog (Dispose, Finalization, and Resource Management)

    HTH GL
    William Wegerson (www.OmegaCoder.Com)
    • Proposed as answer by CiaranODonnell Wednesday, March 31, 2010 3:57 PM
    • Marked as answer by AdityaReddyM Thursday, April 1, 2010 4:14 AM
    Wednesday, March 31, 2010 3:20 PM
    Moderator