Course contentsShow
← C#
Lesson 1731 of 1,90816. Performance and DiagnosticsFree lesson

Managing Large Object Heap Efficiency

Learners will implement strategies to minimize the impact of large object allocations on total application memory.

In this lesson, you will learn how to optimize memory usage by strategically managing objects that land on the Large Object Heap (LOH) to prevent performance degradation.

Understanding the LOH Threshold

In .NET, objects larger than 85,000 bytes are automatically allocated on the Large Object Heap. Unlike generations 0 and 1, which are compacted frequently, the LOH is typically not compacted because moving large memory blocks is computationally expensive. Over time, this leads to heap fragmentation, where free memory is scattered in small, unusable chunks, eventually triggering an OutOfMemoryException even when total free memory seems sufficient.

Strategies for Efficiency

To minimize LOH impact, your primary goal is to reuse large buffers rather than allocating them repeatedly.

1. Renting from ArrayPool

Instead of instantiating a new large array (e.g., byte[] buffer = new byte[100000]) every time a method is called, use System.Buffers.ArrayPool<T>. This allows you to "rent" an existing array from a pool and "return" it once finished.

using System.Buffers;

public void ProcessLargeData(int size)
{
    var pool = ArrayPool<byte>.Shared;
    byte[] buffer = pool.Rent(size);
    try
    {
        // Use the buffer...
    }
    finally
    {
        pool.Return(buffer);
    }
}

2. Slicing with Span<T>

Avoid creating multiple large arrays when processing subsets of data. By using Span<T> or Memory<T>, you can reference segments of an existing large buffer without allocating new memory on the heap. This allows you to work with sub-sections of your data efficiently without triggering new LOH allocations.

3. Structs for Small Aggregates

If your large object consists of a collection of smaller items, evaluate if changing your data structure can keep the allocation below the 85,000-byte limit. While not always possible, breaking monolithic objects into smaller, manageable pieces that stay in Gen 2 (or lower) helps the Garbage Collector manage memory more effectively through standard compaction.

Key Takeaway: The most effective way to manage LOH efficiency is to treat large memory buffers as reusable assets via object pooling rather than disposable allocations.