Phase 15 of 30 · Topic 15.5

Stream Pooling & `RecyclableMemoryStream` Optimization

1Concept

Creating and disposing `MemoryStream` objects creates large byte arrays on the Large Object Heap (LOH). Microsoft's `RecyclableMemoryStream` pools memory in chunks to completely prevent LOH fragmentation.

2Architecture Diagram

Standard MemoryStream:
new MemoryStream(10MB) ──> Allocates on Large Object Heap (LOH) ──> Causes GC Gen 2 stalls!

Pooled RecyclableMemoryStream:
GetStream() ──> Leases pooled 128KB buffer blocks ──> Returns to pool on Dispose() (Zero LOH Pressure!)

3Code Example

C# 13 & .NET 9
using System;
using System.Buffers;
using System.IO;

public class StreamPoolingDemo
{
    public static void Main()
    {
        // Using ArrayPool for zero-allocation stream buffers
        byte[] pooledBuffer = ArrayPool<byte>.Shared.Rent(4096);
        try
        {
            using var ms = new MemoryStream(pooledBuffer, 0, 4096, writable: true);
            ms.Write([1, 2, 3, 4], 0, 4);
            Console.WriteLine($"Stream Position: {ms.Position} bytes written to pooled buffer.");
        }
        finally
        {
            ArrayPool<byte>.Shared.Return(pooledBuffer);
        }
    }
}

4Expected Output

Stream Position: 4 bytes written to pooled buffer.

5Key Takeaways

  • Always return rented arrays to `ArrayPool<T>.Shared` inside `finally` blocks.
  • Never access rented arrays after returning them to the pool.
  • Use `Microsoft.IO.RecyclableMemoryStream` for production web APIs.