Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Debugging .NET memory leaks - how to know what is holding a reference to what?

I am working on a .NET application where there appears to be a memory leak. I know the text-book answers, that events should be unsubscribed, disposable objects should be disposed etc...

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

public class Foo
{
   // Ctor
   public Foo()
   {
   }

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

In the test harness, I am creating a single instance of Foo (which in turn creates and interacts with hundreds of other types) then removing it and invoking the Garbage collector.

I am finding the Foo Finalizer is never called. I have a similar class with this setup which is finalized as a control test.

So my question is this:

How can I determine using commercial or open source tools exactly what is holding a reference to Foo?

I have a professional license to dotTrace Memory profiler but can't figure out from the help files how to use it.

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

like image 636
Dr. Andrew Burnett-Thompson Avatar asked Jun 21 '12 07:06

Dr. Andrew Burnett-Thompson


People also ask

How detect memory leak in .NET application?

Usage of memory profiler to detect a memory leak DotMemory, SciTech Memory Profiler, and ANTS Memory Profiler are the most popular.NET memory profilers. If you have Visual Studio Enterprise, you may also use a "free" profiler. Memory profilers all work in the same way.


2 Answers

Debugging memory leaks can be quite involved process and requires thorough understanding of your program logic and at least some .Net internals (especially garbage collector behaviour).

For more information see the following links:

Good introduction

  • http://msdn.microsoft.com/en-us/library/ee658248.aspx

Hands-on course:

  • http://www.dotnetfunda.com/articles/article508.aspx
  • http://www.dotnetfunda.com/articles/article524.aspx

GC and .Net internals

  • http://blogs.msdn.com/b/tess/archive/2008/04/17/how-does-the-gc-work-and-what-are-the-sizes-of-the-different-generations.aspx
  • http://msdn.microsoft.com/en-us/magazine/cc163491.aspx
  • http://blogs.msdn.com/b/maoni/archive/2004/06/03/148029.aspx

WinDbg with SOS extension

  • http://www.codeproject.com/Articles/19490/Memory-Leak-Detection-in-NET
  • http://www.simple-talk.com/dotnet/.net-framework/investigating-.net-memory-management-and-garbage-collection/

Good Luck!

like image 70
Oleg Kolosov Avatar answered Sep 20 '22 06:09

Oleg Kolosov


Have a look at the SOS debugger extension (It's free, an can be used within Visual Studio).

You may find this and this helpful to get startet.

If you have succefully set up SOS (this can be tricky sometimes), knowing what holds a reference to what is as easy 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
like image 20
sloth Avatar answered Sep 19 '22 06:09

sloth