Debugging .NET memory leaks - how do you know what keeps a link to what?

I am working on a .NET application where there seems to be a memory leak. I know the answers in a text book that events should be unsubscribed, disposable objects must be deleted, etc.

I have a test post that can reproduce the error. In the finalizer of a certain class, I write to the console

public class Foo { // Ctor public Foo() { } ~public Foo() { Console.WriteLine("Foo Finalized"); } } 

In the test harness, I create one instance of Foo (which, in turn, creates and interacts with hundreds of other types), then deletes it and calls the garbage collector.

I find that Foo Finalizer is never called. I have a similar class with this setting, which ends as a control test.

So my question is:

How can I determine if using commercial or open source exactly what the link to Foo contains?

I have a professional license for the dotTrace Memory profiler, but I cannot figure out how to use it from the help files.

Update: Now I am using dotMemory 4.0 , which is the successor to the (good, but unusable) dotTrace Memory 3.5.

+7
source share
5 answers

The finalizer is not deterministically called, so be sure to use it to track things reliably. If you remove the finalizer and use WeakReference<Foo> instead, you can determine if the object was assembled.

All memory profilers should be able to find such a problem, but with varying degrees of difficulty. I personally used ANTS, which is very easy to use, but not free. This will help you show the reference diagram for the Foo instance, all from the root GC object. When you see this diagram, it is usually easy to determine who is holding the link.

+3
source

You have to look into the debugger SOS extension (free, can be used in Visual Studio).

You can find this and this useful to get startet.

If you have successfully configured SOS (sometimes it can be difficult), knowing that it contains a link to something that is as simple as

 // load sos .load sos // list of all instances of YourTypeName in memory with their method tables !DumpHeap -type YourTypeName // put here the method table displayed by the previous command // it will show you the memory address of the object !DumpHeap -mt 07f66b44 // displays information about references the object at the specified address !GCRoot 02d6ec94 
+6
source

You can use memory profilers to identify memory leaks. Here are some

Memprofiler

ANTS Profiler

+2
source

First, you should not use a finalizer because:

Finalize operations have the following limitations:

  • The exact finalizer execution time during garbage collection is undefined. Resources are not guaranteed for a specific time unless the Close method or the Dispose method is called.

  • Finalizers of two objects are not guaranteed in any particular order, even if one object relates to another. That is, if Object A has a reference to Object B, and both have finalizers, Object B may already be completed when the finalizer of Object A begins.

  • The stream on which the finalizer is running is invalid.

Quote: http://msdn.microsoft.com/en-us/library/system.object.finalize.aspx
Instead, I would suggest using the Dispose method.

Secondly, any memory profiler should be able to find what contains these links. Personally, I used the ANTS Profiler, it is a very good tool and has fairly rich documentation. You can try reading this document: http://downloads.red-gate.com/HelpPDF/ANTS_Memory_Profiler/InstanceCategorizer.pdf A classifier instance maps link chains from object sets to the GC root.

+1
source

All Articles