Partager via


New Article on Detecting Memory Leaks . NET Applications

MSDN has published an excellent article by Fabrice Marguerie entitled “How to Detect and Avoid Memory and Resource Leaks in .NET Applications.” In the article, the author explains how memory leaks are introduced into .NET applications, and what you can do to discover and eliminate them. The code shown in the article is in C#, but the topics covered will likely be useful to a broad range of .NET developers.

 FabriceMarguerie

Figure 1: Fabrice Marguerie is a Microsoft MVP, French Software Architect and Web Entrepreneur with an in-depth understanding of .NET technology.

Fabrice explains his subject in great depth, providing information that will be useful both to advanced developers, and to those with an intermediate-level understanding of .NET development. Features included in the text include:

  • An explanation of how memory and resource leaks occur in .NET application
  • A demonstration of how to detect those leaks
  • A list of common causes of memory leaks and how to avoid them
  • A useful reference section listing a number of tools that can be used to help you find and manage leaks

This is a well written article with a wealth of information in it. Hurry on over to the Dev Center and take a look.

References

kick it on DotNetKicks.com

Comments

  • Anonymous
    November 02, 2009
    Thanks a lot Charlie! Please note that the correct address is http://msdn.microsoft.com/en-us/library/ee658248.aspx

  • Anonymous
    November 06, 2009
    The garbage collector was touted as being a foolproof mechanism to prevent us poor dumb programmers from creating memory leaks because we forget to free resources we allocate.  It seems the C++ model is much easier - you just always free resources - kind of like you include the closing curly brace.  Now, with C# and the gc, a programmer must know which objects must be disposed and under what circumstances - it has become a convoluted mess.  Microsoft should either elevate the role of the destructor in C# or, better yet, drop the gc altogether.  

  • Anonymous
    November 08, 2009
    Don: Drop the gc?? That suggestion shows you really don't know much about the CLR.

  • Anonymous
    November 08, 2009
    Drop the GC is not an option. But you are right, that releasing objects in C# it is a real mess. However, this problem is not critical problem like it is in C++ for most cases.

  • Anonymous
    November 10, 2009
    Perhaps teach better programming techniques and so programmers don't start developing and releasing software with leaks until they understand the concepts to a good enough standard. Learn the way of programming without reliance on garbage collection - that was you are responsible for creation and destruction of objects. Learn about memory and how to allocate, use it, free it. Learn about handles and memory associated to not clearing up correctly. To reiterate - learn to code - not code lazily!

  • Anonymous
    November 10, 2009
    The comment has been removed

  • Anonymous
    November 10, 2009
    The comment has been removed

  • Anonymous
    November 10, 2009
    The most common everyday cause for managed objects being leaked remains the Observer pattern, ie, the event subscription which is never removed. It's absolutely incredible that the CLR team has not implemented a true weak delegate to fix this problem.  Ian Griffiths tried to fix this issue and messed up the implementation. At the moment there are no good workarounds to this.  The WeakEvent pattern is klutzy and only works in WPF applications anyway.  The simplest general-purpose solutions use tons of "helper classes" and require lots of code just to hook up and unhook.  And they still depend on some sort of message pumping to free dead listeners on events which aren't firing. This whole mess stems from the lack of a true Delegate class which holds a weak reference to its target.  The CLR gives us a WeakReference, but no WeakDelegate and no way to create one. It's unbelievable that this wasn't added to the 4.0 framework -- this problem has been around for years and no one at Microsoft seems to notice or care about it.  Instead we got the System.IObserver<T> which requires lots custom code on the part of the observed, and doesn't mesh with existing event properties at all. Can anyone from Microsoft comment on this mess?  Is it ever going to be fixed?

  • Anonymous
    November 11, 2009
    Daryl, a request has been opened for this in 2004. Microsoft left the request open since then, but there are no signs of any improvement yet... https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=94154

  • Anonymous
    November 26, 2009
    I agree with Jay and George.  If you actually learn how to program, memory management is no problem.  We now have hords of "developers" who believe it is "impossible" to do without garbage collection.  Let them try and use gc in the kernal:) C# is ok to use for throw-away database query applets - it's quick and easy for that and doesn't require much programming experience.  Real programs with real demands require C++/C/Assember. If you can't control the gc, you have no control of your program and are at the mercy of MS.

  • Anonymous
    November 29, 2009
    The comment has been removed

  • Anonymous
    December 05, 2009
    The comment has been removed

  • Anonymous
    December 06, 2009
    The comment has been removed

  • Anonymous
    December 08, 2009
    If they could make myObject = null actually mean something that would help. Just because you have made it null its still up to the GC to release it whenever it see's fit. Perhaps setting something to null could immediately release it from memory and the GC could still perform its background clear up's in its own time?  

  • Anonymous
    December 08, 2009
    Jon, I agree.  I'm not saying C# is useless - I program in several languages - "fit the task".  That part of my rant was in response to the comment that C++ code leaks - yet the .NET framework and the handful of OSs it's used on was written in C/C++.  Please note my original point - MS should reconsider its implementation of GC or allow opt-out altogether. If the GC is going to manage resources, fine, but it should do so completely, correctly, and consistently.  If not, allow the programmer to do so. Regardless of the language, some applications have performance requirements.  It may be ok for the gc to kick in at will in many applications.  However, if an application has performance-critical requirements, having the gc cut in at an inappropriate time is very frustrating and impedes performance tailoring.

  • Anonymous
    December 09, 2009
    Each language has its merits. C# is good for somethings whereas C++ is good in its own way. Being said that with C# you don't have to do much plumb work since it's already taken care for you however, if you want to be perfectionist then it is upto you.

  • Anonymous
    December 13, 2009
    I'm pretty sure back in the early days of OOP (I'm too young for that I'm afraid) there were programmers everywhere completely resistant to the change to OOP due to the slight performance drop between for example C and C++.  However, I think evryone can now realise the huge benefits in dev time etc by moving over to OOP. Is this not simillar to the move to GC? (Ok not exactly but you got to admit there are parallels). It's early days for GC, and surely it's only going to dramatically improve over the coming years. Anything that reduces complexity of code and reduces the time of a project to me can only be a good thing, and Don, come on man you can't defend code leakage in C++. Fair enough its poor programmers faults not the language, but buggy (in terms of memory leakage) C++ programs are everywhere we look.

  • Anonymous
    December 14, 2009
    I agree with Don.  The people that embrace C# and don't like C++ are people who don't understand pointers.  The GC is frustrating because you have no control.  

  • Anonymous
    December 19, 2009
    The comment has been removed

  • Anonymous
    December 21, 2009
    Don, actually, yes you did say C# was useless ...I quote "C# is ok to use for throw-away database query applets" That's you being an elite snob. I wonder how much real world programming you still do.  It's obvious you're been doing C++ for a long time and are apprently afraid of NOT having pointers.  Seriously guys - I don't NEED pointers.  It's the rare program that does.  You knock yourself out. It's the blanket statements coming from you lot, like if I like C# I must be afraid of pointers, that amuse me.   Basicaly, you guys are like the people that drive in snow.  It's not your driving thats the problem - it's everyone elses.  Your C++ code doesn't stink - everyone else's languages and code that stinks.   Whatever. Do I think C# is the ultimate language?  Nope.  Do I think Windows is a better OS than Mac OS?  Nope.  Do I think I can get the job done faster and better in C# than I can in C++?  Indeed.  Do I think I can make more money coding in windows than mac?  Indeed. And see - this is where you make the mistake.  I'm not even remotely a C# evanglist.  I simply use whatever the best tool is for what I am doing - for me, most of the time, I am here to clean up other people's messes.  No lead time, dirty specs, no QA.  C# fits that bill prety good. And ok I'll take the 'OS' red herring.  I do not feel the need to write my software in a language that has written an OS.  Who. Cares. Why in the WORLD does that matter?  Is that really the first question you ask before you consider a new language? Thank for the tonights amusement. St. Nick - I like that btw.

  • Anonymous
    December 21, 2009
    Ah, and here is the kicker.  Don, you have enough time on your hands to come troll a blog that you KNEW when you saw the title you weren't going to have anything useful to say. And you keep coming back.  How amusing. Keep on trolling.

  • Anonymous
    December 23, 2009
    One reason of memory leaks is working thread. I've spent few hours yesterday trying to understand who keeps reference to my window. The problem was in the BackgroundWorker thread that I didn't exit on Window.Close. I totally forgot to cancel async operation and as result thread was working even after I closed window. Once again want to say simple rule: if your code has working thread - it should exit this thread on Dispose() and do not forget call Dispose() at the end. Best Regards

  • Anonymous
    December 23, 2009
    The comment has been removed

  • Anonymous
    January 18, 2010
    You guys, who don't like the GC: Why do you use such an inefficient programming language as C++ at all? You should stick to assembler, that way you have total control over your code! ;-)

  • Anonymous
    January 18, 2010
    All this reminds me of the battles that use to be waged between Delphi and C++ developers as to which was the better language. I ended up believing that most of the time decisions are guided by one of two rules:

  1. Use the right tool for the job, when that distinction can be clearly discerned, which is infrequently.
  2. Use the tool you know best or for which you have the best resources. For instance, both C# and VB.NET are good languages. They are so equal that the best choice is usually the language you know best. If most of the developers on a team know C# better than VB, then go with C#. But so often the choices are blurry and hard to make. If you need a small executable that executes very fast, then C++ might be better than C# -- in some cases. If you need to get work done quickly, then C# is probably better than C++, in most cases. If you are an expert in C++ and don't know C# at all, is it worth learning C# just to try to complete one project more quickly? Well, maybe, in some cases. In other cases, no. Language wars are not always that useful, and they never seem to end in anything resembling a clear victory for one side or the other. But the discussions are interesting, and fun, so long as one doesn't get too hooked by them! It's always worth stepping back to the meta-level and thinking about language wars in general, rather than one language war in particular. In general, no one ever wins a language war, and the primary benefit is just in the opportunity to learn a little more about the strengths and weaknesses of whatever tools are being discussed. If you are learning something, then go for it, if you are just getting angry and frustrated, then maybe there is some better way to pass the time.
  • Charlie
  • Anonymous
    January 26, 2010
    Generally good, reasonable advice, Charlie. However, I would add a caveat : "If you need a small executable that executes very fast, then C++ might be better than C# -- in some cases. If you need to get work done quickly, then C# is probably better than C++, in most cases". ...and if you want a small executable that executes very fast AND you need to get work done quickly, Delphi is still better than either of them in most cases. Hugely disappointing to see that the old MS development tool false dichotomy of trading off power against ease of development is as alive and well as it ever was. Reminds me of the Hobson's choice of either VB or VC++ from back in the day...

  • Anonymous
    January 27, 2010
    Thank you, Lurkio. As an old and long term fan of Delphi, I would agree that it is definitely a great tool for building native applications.

  • Anonymous
    March 09, 2010
    I just can't believe the foolish person who thinks that C++ eliminates memory leaks, or even has less than a CLR based language. Sorry dude, I've had to debug memory leaks from even elite programmers (at Microsoft and elsewhere). Same thing in C.   Good memory management requires mental rigor, which for some reason you associate with C++ but there is little correlation. In my experience the only difference between a leak in C++ and in C# is that the CLR tools are better and easier to track down problems. The managed heap is way better and more efficient than most of the heaps in native programming. At Microsoft we had an amazing flexible heap that could be tuned nicely, but it was complicated. I'd rather debug the CLR, thanks much. The best part of the CLR is that you can use C++ where it is strong and C# where it is strong. It sounds like you've painted yourself into a corner where you feel threatened by new technology. Good luck with that.