♻️ Stop Allocating Temporary Arrays
new byte[1024] allocates and GC collects. ArrayPool<T> reuses arrays. Zero allocation for temporary buffers. Huge GC reduction.
📝 Basic ArrayPool Usage
using System.Buffers; // Rent array (might be larger than requested) byte[] buffer = ArrayPool.Shared.Rent(1024); try { // Use buffer await stream.ReadAsync(buffer, 0, 1024); Process(buffer); } finally { // Return to pool (must always return!) ArrayPool .Shared.Return(buffer); } // Clear buffer before returning (if needed) ArrayPool .Shared.Return(buffer, clearArray: true);
🎯 Real-World Example
public async Task ProcessLargeFileAsync(string path)
{
byte[] buffer = ArrayPool.Shared.Rent(81920); // 80KB
try
{
using var fs = File.OpenRead(path);
int bytesRead;
while ((bytesRead = await fs.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await ProcessChunkAsync(buffer.AsMemory(0, bytesRead));
}
}
finally
{
ArrayPool.Shared.Return(buffer);
}
}
// Custom pool for specific sizes
var customPool = ArrayPool.Create(maxArrayLength: 1024, maxArraysPerBucket: 50);
💡 Performance Impact
- Without pool: 1M allocations → 1M GC collections
- With pool: 1M uses → 0 allocations after warmup
- Perfect for network buffers, parsing, serialization
- Works with Span<T> and Memory<T>
- Must return rented arrays (use try/finally)
“Network parser allocated 1GB of temporary arrays per minute. GC paused 10% of time. ArrayPool eliminated allocations. GC pressure gone. Performance doubled.”
