What is the Large Object Heap, and why is it a concern?

C# Memory Advanced 3–5 Yrs5+ Yrs Conceptual 1 min read

Quick Answer

Objects of 85,000 bytes or more (mostly big arrays and strings) go on the Large Object Heap. The LOH is collected only during a Gen 2 GC (expensive) and by default is not compacted, so it fragments — free space exists but not in a contiguous block big enough for the next large allocation.

The runtime puts any allocation of about 85 KB or more on a separate heap, the LOH — think large byte arrays, big strings, buffers. Two things make it a problem. First, it's only cleaned up in a full Gen 2 collection, which is the slow kind. Second, it isn't compacted by default, so after a while you get fragmentation — plenty of total free memory but no single gap large enough, which can even throw OutOfMemory. The fix is to stop allocating large short-lived buffers: pool them with ArrayPool, or restructure to stream data in chunks rather than materialising it all at once.

  • Avoid churning large buffers: reuse with ArrayPool<T>.Shared, or stream instead of loading a whole file/response into one array.
  • You can force a one-off compaction: GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; — use sparingly.
  • Watch for hidden large allocations: List<T> growth, MemoryStream.ToArray(), big LINQ ToList(), serialization buffers.