.NET6中GC.GetGCMemoryInfo返回异常大值问题求助
GC.GetGCMemoryInfo() in .NET 6 Let me break down what's happening here and how to fix it:
The Root Cause: Unsigned Integer Overflow
The weirdly large values (like 500GB for Gen2) and negative deltas you're seeing are almost certainly due to unsigned integer overflow when handling the SizeBeforeGc and SizeAfterGc properties.
These properties are of type nuint (unsigned integer), but if you're implicitly converting them to signed integers (like int or long) without accounting for this, you'll get incorrect values when SizeBeforeGc is larger than SizeAfterGc (which happens when GC reclaims memory). The negative delta you see is the signed interpretation of an unsigned underflow, and when that negative value is treated as an unsigned number again (e.g., in logging), it becomes a massive positive number.
Fixed Code Example
Here's how to correctly handle the unsigned values to avoid overflow issues:
var gcInfo = GC.GetGCMemoryInfo(); var gcIndex = gcInfo.Index; // Iterate through each generation (0, 1, 2, and LOH at index 3) for (int gen = 0; gen < gcInfo.GenerationInfo.Length; gen++) { var genInfo = gcInfo.GenerationInfo[gen]; nuint sizeAfterGc = genInfo.SizeAfterGc; nuint sizeBeforeGc = genInfo.SizeBeforeGc; // Calculate delta safely: cast to long only after computing the unsigned difference // If sizeAfterGc < sizeBeforeGc, the unsigned difference will wrap around, so we cast to long to get a negative value long delta = (long)(sizeAfterGc - sizeBeforeGc); // Log with correct values Console.WriteLine($"Gen {gen} Heap Size: {sizeAfterGc} ({delta}) (#{gcIndex})"); }
Confirming GenerationInfo Meaning
To answer your core question: Yes, the GenerationInfo entries in GCMemoryInfo do represent the heap state immediately after the GC cycle with the corresponding Index. Each index in the array maps to:
- Index 0: Generation 0
- Index 1: Generation 1
- Index 2: Generation 2
- Index 3: Large Object Heap (LOH)
Even though .NET 5+ merged LOH into Gen2's recycling strategy, this API still retains the separate entry for LOH for compatibility and clarity.
Why Task Manager and GC Values Don't Match
Quick note on the discrepancy with Task Manager's 1.5GB value: Task Manager shows the entire process's private working set, which includes:
- Managed heap memory (what
GC.GetGCMemoryInforeports) - Unmanaged memory used by your app or dependencies
- JIT-compiled code
- Loaded assembly files
- Other process-level resources
So even after fixing the overflow, you shouldn't expect the GC-reported values to exactly match Task Manager—they're measuring different things.
内容的提问来源于stack exchange,提问作者Nick W

