Home > Back-end >  Mysterious very large (wrong) number reported by GetGCMemoryInfo().GCGenerationInfo.SizeAfterBytes
Mysterious very large (wrong) number reported by GetGCMemoryInfo().GCGenerationInfo.SizeAfterBytes

Time:01-13

Previously im using PerfCounter to inspect the heap but seems they are no longer usable after moved to .NET5 .

Now, Im trying to use the GetGCMemoryInfo API, with below code:

 var info = GC.GetGCMemoryInfo();
 var index = info.Index;

 var genInfos = info.GenerationInfo;
            
 var genInfo = genInfos[0]; // and 1, 2, 3 (Loh)
 var delta = genInfo.sizeAfterGc - genInfo.sizeBeforeGc;
 
 // Write Log: sizeAfterGc (delta) (#index)

My app, in task manager, used to report ~1.5G memory usage. But sizeAfterGc give me some very big number, which I believe is wrong.

Some sample output from my app:

Gen 0 Heap Size: 4950350920 (-2591581216) (#870)
Gen 1 Heap Size: 3273780000 ( 4675848) (#870)
Gen 2 Heap Size: 503084649368 ( 833581192) (#870)

which says 5GB Gen0, 3GB Gen1 and 500GB Gen2.

Now if I put my app running long enough, I can see the number of all generations keep increasing.

For example,

Around Start of App: 
Gen 0 Heap Size: 63270464 (-574326464) (#96)

~20-mins later:
Gen 0 Heap Size: 12494958280 (-2876572192) (#1787)

~2-hrs later:
Gen 0 Heap Size: 108851806072 (-6817850448) (#13303)

Except from maoni's blog post, I couldn't find much info on how this api should be used/coordinated.

Im not quite sure if GC.GetGCMemoryInfo(); should be called like this? I guess this reported the latest GC (as any kind), and the GenerationInfo attached to this run of GC should still be relevant to inspect for all heaps at a given time?

ie. if this gives GCMemoryInfo #870, then I should expect the GenerationInfo represents the heap status after #870 is performed?

Would like to seek help from anyone who might have experience this, big thanks!

(Im testing this on .NET6)

CodePudding user response:

There was a bug in this API that has been fixed in PR fix for generation info in GCMemoryInfo by Maoni0 · Pull Request #60309 · dotnet/runtime - generation info was not zeroed after the GC, so it was always increasing.

It was discovered at the time of .NET 6 release but as we can see in the PR, it will be backported to .NET 6 soon.

To track generation sizes and other GC-related metrics you can use EventCounters instead, in-proc or out-proc.

  • Related