views:

273

answers:

5

I have an object, which lives forever. I am deleteing all references I can see, to it after using it, but it still not collected. Its life cycle is pretty sophisticated so I can't be sure that all references been cleared.

if ( container.Controls.Count > 0 )
{ 
    var controls = new Control[ container.Controls.Count ];
    container.Controls.CopyTo( controls, 0 );

    foreach ( var control in controls ) 
    { 
         container.Controls.Remove( control );
         control.Dispose();
    }

    controls = null; 
}

GC.Collect();
GC.Collect(1);
GC.Collect(2);
GC.Collect(3);

How can I find out what references does it still have? Why is it not collected?

A: 

It is not collected because you haven't removed all references to it. The GC will only mark objects for collection if they have no roots in the application.

What means are you using to check up on the GC to see if it has collected your object?

Andrew Hare
+1  A: 

The garbage collection in .NET is not a counting scheme (such as COM), but a mark-and-sweep implementation. Basically, the GC runs at "random" times when it feels the need to do so, and the collection of the objects is therefore not deterministic.

You can, however, manually trigger a collection (GC.Collect()), but you may have to wait for finalizers to run then (GC.WaitForPendingFinalizers()). Doing this in a production app, however, is discouraged, because it may affect the efficiency of the memory management (GC runs too often, or waits for finalizers to run). If the object still exists, it actually still has some live reference somewhere.

Lucero
+3  A: 

Try using a memory profiler, (e.g. ants) it will tell you what is keeping the object alive. Trying to 2nd guess this type of problem is very hard.

Red-gate gives 14 days tail that should be more then enough time to tack down this problem and decide if a memory profiler provides you with long term value.

There are lots of other memory profilers on the market (e.g. .NET Memory Profiler) most of them have free tails, however I have found that the Red-Gate tools are easy to use, so tend try them first.

Ian Ringrose
Thanks, I'll try!
er-v
They also have some free training videos (and documents) etc that explain how the .net garbage collector works that you may find useful.
Ian Ringrose
@er-v: your object may have been collected but the memory may not have been reclaimed by Windows. The framework doesn't have to return memory to the OS.
sixlettervariables
Thanks. Memory profiler is the thing I needed.
er-v
+2  A: 

You'll have to use Windbg and Sosex extension.

The !DumpHeap and !GCRoot commands can help you to identify the instance, and all remaining references that keep it alive.

Romain Verdier
+2  A: 

I've been using .NET Memory Profiler to do some serious memory profiling on one of our projects. It's a great tool to look into the memory management of your app. I don't get paid for this info :) but it just helped me alot.

Bjorn Bailleul