You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

64位进程中LOH碎片会引发OOM吗?.NET GC演示代码疑问

Understanding LOH Fragmentation in .NET 4.6 (64-bit)

Great question—let’s break this down step by step to explain why your code isn’t hitting the expected OutOfMemoryException, and address your core questions about LOH behavior in .NET 4.6 and 64-bit environments.

Does .NET 4.6 automatically compact the LOH?

Back in .NET 4.5.1, the runtime added optional LOH compaction via the GCSettings.LargeObjectHeapCompactionMode property. In .NET 4.6 and later, this behavior got a key update:

  • By default, the runtime will automatically compact the LOH during a full garbage collection when system memory pressure is high, or when you explicitly trigger it (like setting GCLargeObjectHeapCompactionMode.CompactOnce before calling GC.Collect()).
  • In your code, after clearing the big list and running GC.Collect(), the .NET 4.6+ runtime likely performed LOH compaction. This merged the scattered 10MB free blocks into a single contiguous chunk—making the subsequent 20MB allocation possible, so no OutOfMemoryException was thrown.

Is LOH fragmentation no longer a problem in 64-bit environments?

No, it’s not gone—but it’s far less likely to cause immediate failures compared to 32-bit systems:

  • 32-bit processes have a tiny 4GB address space (usually only 2GB available for user-mode code). Even small amounts of LOH fragmentation can quickly eat up all contiguous memory blocks needed for large objects.
  • 64-bit processes have a massive address space (theoretical 16EB, with practical limits like 256GB on Windows Server). This means there’s way more room to allocate non-contiguous blocks, so fragmentation takes much longer to become critical.
  • That said, long-running apps (like background services) that repeatedly allocate and free large objects of varying sizes can still accumulate LOH fragmentation over time. Eventually, this can lead to OutOfMemoryException when a sufficiently large contiguous block can’t be found.

Why isn’t your code triggering the expected OutOfMemoryException?

Your test relies on LOH fragmentation blocking a 20MB allocation after freeing multiple 10MB blocks. Here’s why it’s not working in .NET 4.6 64-bit:

  1. The automatic LOH compaction in .NET 4.6+ is fixing the fragmentation when you call GC.Collect(), turning scattered free space into a single usable block.
  2. To reproduce the original fragmentation behavior, you need to disable automatic compaction. Add this line right before GC.Collect():
    GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.None;
    
    With this setting, the LOH won’t be compacted during the full GC. The scattered free space won’t be merged, and the 20MB allocation will fail with OutOfMemoryException as expected.

Quick Debugging Tips

You can verify LOH state with tools like WinDbg:

  • Use !dumpheap -stat to check object distributions across heaps.
  • Use !eeheap -gc to view heap segments and free space.
  • Use !address -summary to see overall memory usage and fragmentation.

内容的提问来源于stack exchange,提问作者Nahum Timerman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:25:57