Memory Leak And The IDisposable Pattern

April 29, 2008

Memory Leak And The IDisposable Pattern


Sunday morning.
I return to my current project after two weeks that I wasn’t there.
The “welcome party” is a story about the crisis of the last two weeks.
Apparently, we have a memory leak and in the past two weeks nobody
solved the problem. The production servers work for five hours and then
the memory usage is going over 900MB and the servers crush and the application
crushes with them. The system administrators make a recycle to the application
and the story goes on again.
Of course the users are angry because it was a new release of the application.
The details I get are that the memory is full of objects that the garbage collector
isn’t able to finalize.
After a short brainstorm with two of my colleagues (Ran and Yossi) a lead to the
solution is raised and I find the reason for the memory leak.
We use an enterprise library LogWriter object in order to log messages to our database.
The LogWriter implement the IDisposable interface because two of its members
(LogWriterStructureHolder and ILogWriterStructureUpdater) need to be disposed.
The class that wrapped the LogWriter didn’t implement the IDisposable interface
and therefore the memory wasn’t released. Also, there is mass usage of the wrapper
class in the application and the result – a memory leak.
The solution was simple. Use the IDisposable pattern in order to dispose the wrapper
class and wrap every usage of the wrapper class with the using clause.
Currently, the memory usage of the servers is 120MB and the problem was solved.


IDisposable Pattern
The IDisposable pattern isn’t one of the a classic patterns. It’s a pattern suggested in
MSDN to implement the IDisposable interface. You should be familiar with the pattern
or with the interface because it’s a basic thing to know about the .Net framework.

How to Use IDisposable Pattern
Lets look at a code example.




    public class DisposeObject : IDisposable


    {


        #region Members


 


        private bool _disposed = false;


 


        #endregion


 


        #region IDisposable Members


 


        ~DisposeObject()


        {


            Dispose(false);


        }


 


        /// <summary>


        /// Dispose the current object


        /// </summary>


        public void Dispose()


        {


            Dispose(true);


        }


 


        private void Dispose(bool disposing)


        {


            if (!_disposed)


            {


                if (disposing)


                {


                    // clean up resources


                    CleanUp();


 


                    // The object will be cleaned up only if the method


                    // gets true – we are in the Dispose method.


                    // Therefore, you should call GC.SupressFinalize to


                    // take this object off the finalization queue


                    // and prevent finalization code for this object


                    // from executing a second time.


                    // Taken from MSDN.


                    GC.SuppressFinalize(this);


                }


 


                // dispose occurred


                _disposed = true;


            }


        }


 


        private void CleanUp()


        {


            // put here the code to dispose all managed


            // and unmanaged resources


        }


 


        #endregion


    }


 



The code is self explanatory.


Conclusion
Hope that writing this post will help you think about IDisposable pattern if
you have a memory leak in managed environment like .Net. The reason isn’t always
the lack of IDisposable but it’s a good start when you look for memory leaks’ reason.
 

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

2 comments

  1. kolbisApril 30, 2008 ב 15:27

    Good to hear you solve it!

    Reply
  2. Gil FinkApril 30, 2008 ב 16:48

    Thanks Guy.
    It was a team effort and I’m not taking all the credit to myself.

    Reply