.net - tools - windows memory leak

Anatomy of a “Memory Leak” (10)

In .NET perspective:

  • What is a memory leak ?
  • How can you determine whether your application leaks? What are the effects?
  • How can you prevent a memory leak?
  • If your application has memory leak, does it go away when the process exits or is killed? Or do memory leaks in your application affect other processes on the system even after process completion?
  • And what about unmanaged code accessed via COM Interop and/or P/Invoke?

I guess in a managed environment, a leak would be you keeping an unnecessary reference to a large chunk of memory around.

Absolutely. Also, not using the .Dispose() method on disposable objects when appropriate can cause mem leaks. The easiest way to do it is with a using block because it automatically executes .Dispose() at the end:

StreamReader sr;
using(sr = new StreamReader("somefile.txt"))
    //do some stuff

And if you create a class that is using unmanaged objects, if you're not implementing IDisposable correctly, you could be causing memory leaks for your class's users.

All memory leaks are resolved by program termination.

Leak enough memory and the Operating System may decide to resolve the problem on your behalf.

I found memprofiler a very good help when finding memory leaks in .Net. It's not free like the Microsoft CLR Profiler, but is faster and more to the point in my opinion. A

I guess in a managed environment, a leak would be you keeping an unnecessary reference to a large chunk of memory around.

I will concur with Bernard as to in .net what a mem leak would be.

You could profile your application to see its memory use, and determine that if its managing a lot of memory when it should not be you could say it has a leak.

In managed terms I will put my neck on the line to say it does go away once the process is killed/removed.

Unmanaged code is its own beast and if a leak exists within it, it will follow a standard mem. leak definition.

I would define memory leaks as an object not freeing up all the memory allocated after it has completed. I have found this can happen in your application if you are using Windows API and COM (i.e. unmanaged code that has a bug in it or is not being managed correctly), in the framework and in third party components. I have also found not tiding up after using certain objects like pens can cause the issue.

I personally have suffered Out of Memory Exceptions which can be caused but are not exclusive to memory leaks in dot net applications. (OOM can also come from pinning see Pinning Artical ). If you are not getting OOM errors or need to confirm if it is a memory leak causing it then the only way is to profile your application.

I would also try and ensure the following:

a) Everything that implements Idisposable is disposed either using a finally block or the using statement these include brushes, pens etc.(some people argue to set everything to nothing in addition)

b)Anything that has a close method is closed again using finally or the using statement (although I have found using does not always close depending if you declared the object outside the using statement)

c)If you are using unmanaged code/windows API's that these are dealt with correctly after. (some have clean up methods to release resources)

Hope this helps.

Strictly speaking, a memory leak is consuming memory that is "no longer used" by the program.

"No longer used" has more than one meaning, it could mean "no more reference to it", that is, totally unrecoverable, or it could mean, referenced, recoverable, unused but the program keeps the references anyway. Only the later applies to .Net for perfectly managed objects . However, not all classes are perfect and at some point an underlying unmanaged implementation could leak resources permanently for that process.

In all cases, the application consumes more memory than strictly needed. The sides effects, depending on the ammount leaked, could go from none, to slowdown caused by excessive collection, to a series of memory exceptions and finally a fatal error followed by forced process termination.

You know an application has a memory problem when monitoring shows that more and more memory is allocated to your process after each garbage collection cycle . In such case, you are either keeping too much in memory, or some underlying unmanaged implementation is leaking.

For most leaks, resources are recovered when the process is terminated, however some resources are not always recovered in some precise cases, GDI cursor handles are notorious for that. Of course, if you have an interprocess communication mechanism, memory allocated in the other process would not be freed until that process frees it or terminates.

The best explanation of how the garbage collector works is in Jeff Richters CLR via C# book, (Ch. 20). Reading this gives a great grounding for understanding how objects persist.

One of the most common causes of rooting objects accidentally is by hooking up events outisde a class. If you hook up an external event


SomeExternalClass.Changed += new EventHandler(HandleIt);

and forget to unhook to it when you dispose, then SomeExternalClass has a ref to your class.

As mentioned above, the SciTech memory profiler is excellent at showing you roots of objects you suspect are leaking.

But there is also a very quick way to check a particular type is just use WnDBG (you can even use this in the VS.NET immediate window while attached):

.loadby sos mscorwks
!dumpheap -stat -type <TypeName>

Now do something that you think will dispose the objects of that type (e.g. close a window). It's handy here to have a debug button somewhere that will run System.GC.Collect() a couple of times.

Then run !dumpheap -stat -type <TypeName> again. If the number didn't go down, or didn't go down as much as you expect, then you have a basis for further investigation. (I got this tip from a seminar given by Ingo Rammer ).