Search code examples
.netclrgarbage

when .net garbage collector doesn't compact gc heap?


I run the following code

        StringBuilder sb = new StringBuilder();
        Stack  stack = new Stack();
        SynchronizationContext sc = new SynchronizationContext();

        GC.Collect();
        Console.WriteLine("GC. First Execution.");

        stack = null;

        GC.Collect();
        Console.WriteLine("GC. Second Execution.");

        GC.Collect();
        Console.WriteLine("GC. Third Execution.");

When debugging this code with SOS I see that after First Execution of GC addresses are following:

!dso
...
0239b5f8 System.Threading.SynchronizationContext
0239b5a8 System.Collections.Stack
0239b560 System.Text.StringBuilder
...

After Second Execution there is no 'stack' object in the heap, but other addresses are:

!dso
...
0239b5f8 System.Threading.SynchronizationContext
0239b560 System.Text.StringBuilder
...

So the 'stack' object was collected, but sc (SynchronizationContext) object was not relocated in the memory to be compacted. We have a gap in the memory

!do 0239b5a8
Free Object
Size:        80(0x50) bytes

After Third Execution situation is the same.

Why does it happen? Why 'compact' operation is not performed in this case?

Thank you.


Solution

  • The GC is lazy to be efficient. It will not actually free or as you say 'compact' until it needs to. The object has been moved to a dispose queue.

    You can wait days and not see it clean up. It will clean up when resources are low and it needs to.