Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Counting total objects queued for garbage collection

I wanted to add a small debug UI to my OpenGL game, which will be updated frequently with various debugging options/output displays. One thing I wanted was a constant counter that shows active objects in each generation of the garbage collector. I don't want names or anything, just a total count; something that I can eyeball when I do certain things within the game.

My problem, however, is that I can't seem to find a way to count the total objects currently alive in the various generations.

I even considered keeping a global static field, which would be incremented within every constructor and decremented within class finalizers. This would require hand-coding said functionality into every class though, and would not solve the problem of a "per-generation total".

Do you know how I could go about doing this?

like image 821
Krythic Avatar asked Nov 27 '25 05:11

Krythic


1 Answers

(Question title:) "Counting total objects queued for garbage collection"

(From the question's body:) "My problem, however, is that I can't seem to find a way to count the total objects currently alive in the various generations."

Remark: Your question's title and body ask for opposite things. In the title, you're asking for the number of objects that can no longer be reached via any GC root, while in the body, you're asking for "live" objects, i.e. those that can still be reached via any GC root.

Let me start by saying that there might not be any way to do this, basically because objects in .NET are not reference-counted, so they cannot be immediately marked as "no longer needed" when the last reference to them disappears or goes out of scope. I believe .NET's mark-and-compact garbage collector only discovers which objects are alive and which can be reclaimed during an actual garbage collection (during the "mark" phase). You however seem to want this information in advance, i.e. before a GC occurs.

That being said, here are perhaps your best options:

  1. Perhaps your best bet in .NET's managed Framework Class Library are performance counters. But it doesn't look like there are any suitable counters available: There are performance counters giving you the number of allocated bytes in the various GC generations, but AFAIK no counters for the number of live/dead objects.

  2. You might also want to take a look at the CLR's (i.e. the runtime's) unmanaged, COM-based Debugging API. Given that you have retrieved an ICorDebugProcess5 interface, these methods might be of interest:

    • ICorDebugProcess5::EnumerateGCReferences method:

    "Gets an enumerator for all objects that are to be garbage-collected in a process."

    See also this answer to a similar question on SO.

    Note that this is about objects that are to be garbage-collected, not about live objects.

    • ICorDebugProcess5::GetGCHeapInformation method:

    "Provides general information about the garbage collection heap, including whether it is currently enumerable."

    If it turns out that the managed heap is enumerable, you could use…

    • ICorDebugProcess5::EnumerateHeap method:

    "Gets an enumerator for the objects on the managed heap."

    The objects returned by this enumerator are of this type:

    • COR_HEAPOBJECT structure:

    "Provides information about an object on the managed heap."

    You might not be actually interested in these details, but just in the number of objects returned by the enumerator.

    (I haven't used this API myself, perhaps there exists a better and more efficient way.)

  3. In Sept 2015, Microsoft published a managed library called clrmd aka Microsoft.Diagnostics.Runtime on GitHub. It is based on the same foundation as the unmanaged debugging API mentioned above. The project includes documentation about enumerating objects in the GC heap.

Btw. there is an extremely informative book out there by Ben Watson, "Writing High-Performance .NET Code", which includes solid tips on how to make .NET memory allocation and GC more efficient.

like image 119
stakx - no longer contributing Avatar answered Nov 29 '25 18:11

stakx - no longer contributing



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!