Garbage collection of local objects

Viewed 323

I wrote a small Console app experiment:

static void Main()
{
    int GetTotalCollections()
    {
        var total = 0;

        for (var generation = 0; generation <= GC.MaxGeneration; generation++)
            total += GC.CollectionCount(generation);

        return total;
    }

    CreateGarbage();

    WriteLine("Number of collections occurred: {0}", GetTotalCollections());
}

static void CreateGarbage()
{
    WriteLine(new object().GetHashCode());
    WriteLine(new object().GetHashCode());
    WriteLine(new object().GetHashCode());
    ReadKey();
}

When I run it in Release mode without the debugger attached, I get 0 collections for all the generations.

As it seemed weird, I attached WinDbg to the process and !dumpheap -live does not show the objects whereas !dumpheap does. Unfortunately -live is not part of the official documentation for SOS, but I was assuming it showed only uncollected objects.

Is the GC collecting and not reporting it (as it should be in this scenario) or have I misunderstood the !dumpheap -live output? (maybe showing only object with a GC root?)

If I allocate more objects to be sure I trigger a collection (or invoke GC.Collect) I get a collection count increase, but still the same output in WinDbg:

static void GetValue()
{
    for (var i = 0; i < 1000000; i++)
        new object();

    ReadKey();
}

EDIT: The last sentence was an oversight (which caused the confusion), if I force the collection, !dumpheap -stat does not show the objects any more as expected (I just forgot to run the app from WinDbg before pressing a key to force the collection.)

!dumpheap -stat shows uncollected objects both live and dead and !dumpheap -stat -live shows only objects with a GC root as @Thomas answered. Once collected they disappear from the output of all the commands.

2 Answers
Related