How to use ArrayPool and MemoryPool in C#

By FoxLearn 1/7/2025 9:19:45 AM   124
Utilize array pooling and memory pooling in C# to reduce memory allocations and enhance application performance.

Understanding ArrayPool and Its Importance

The ArrayPool class in the System.Buffers namespace is a high-performance pool for reusing managed arrays, designed to minimize allocations and improve performance in scenarios where arrays are frequently reused. Defined as an abstract class, ArrayPool<T> helps avoid the overhead of repeatedly creating and destroying arrays, which can strain the garbage collector due to frequent memory allocation and deallocation.

By utilizing an ArrayPool, you can reserve arrays in advance and rent them out in a thread-safe manner when needed.

The ArrayPool class in C# can be used in three ways:

  • Accessing a shared instance via the ArrayPool.Shared property.
  • Creating a new instance using the static ArrayPool.Create method.
  • Extending the ArrayPool class to create a custom implementation.

For example, how to rent an array from the ArrayPool:

var sharedPool = ArrayPool<int>.Shared;
var rentedArray = sharedPool.Rent(15);

In this example, the rentedArray is an integer array with space for 15 elements, allowing you to store up to 15 integer values.

You can also rewrite the process of renting an array from the ArrayPool as follows:

var rentedArray = ArrayPool<int>.Shared.Rent(10);

To return the array to the pool, call the Return method:

ArrayPool<int>.Shared.Return(rentedArray);

You can also create a new instance of ArrayPool using the ArrayPool.Create method:

var arrayPool = ArrayPool<int>.Create(4, 15);
var rentedArray = arrayPool.Rent(15);

Additionally, you can create your own custom array pool class by extending ArrayPool:

public class CustomArrayPool<T> : ArrayPool<T>
{
    public override T[] Rent(int minimumLength)
    {
        throw new NotImplementedException();
    }
    
    public override void Return(T[] array, bool clearArray = false)
    {
        throw new NotImplementedException();
    }
}

The MemoryPool class from System.Buffers helps manage memory blocks, reducing the pressure on garbage collection by reusing allocated memory.

static void Main(string[] args)
{
    var memoryPool = MemoryPool<int>.Shared;
    var arrayPool = ArrayPool<int>.Create(4, 15);
    var rentedArray = arrayPool.Rent(15);
    for (int i = 0; i < 15; i++)
    {
        rentedArray[i] = i + 1;
    }
    for (int j = 0; j < 15; j++)
    {
        Console.WriteLine(rentedArray[j]);
    }
    arrayPool.Return(rentedArray);
    Console.ReadKey();
}

ArrayPool vs MemoryPool:

  • ArrayPool rents arrays via the Shared property, and is ideal for scenarios where arrays are repeatedly created and destroyed.
  • MemoryPool rents IMemoryOwner implementations and is suitable when working with Memory instances. It is used to allocate and reuse memory blocks dynamically, offering more flexibility for memory management than array pools.

Object pooling (like ArrayPool and MemoryPool) is a great way to reduce overhead by reusing objects or memory rather than creating new ones each time.