optimizing-memory-allocation

.NET Memory Efficiency, Zero Allocation

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "optimizing-memory-allocation" with this command: npx skills add christian289/dotnet-with-claudecode/christian289-dotnet-with-claudecode-optimizing-memory-allocation

.NET Memory Efficiency, Zero Allocation

A guide for APIs that minimize GC pressure and enable high-performance memory management.

Quick Reference: See QUICKREF.md for essential patterns at a glance.

  1. Core Concepts
  • .NET CLR GC Heap Memory Optimization

  • Understanding Stack allocation vs Heap allocation

  • Stack-only types through ref struct

  1. Key APIs

API Purpose NuGet

Span<T> , Memory<T>

Stack-based memory slicing BCL

ArrayPool<T>.Shared

Reduce GC pressure through array reuse BCL

DefaultObjectPool<T>

Object pooling Microsoft.Extensions.ObjectPool

MemoryCache

In-memory caching System.Runtime.Caching

  1. Span, ReadOnlySpan

3.1 Basic Usage

// Zero Allocation when parsing strings public void ParseData(ReadOnlySpan<char> input) { // String manipulation without Heap allocation var firstPart = input.Slice(0, 10); var secondPart = input.Slice(10); }

// Array slicing public void ProcessArray(int[] data) { Span<int> span = data.AsSpan(); Span<int> firstHalf = span[..^(span.Length / 2)]; Span<int> secondHalf = span[(span.Length / 2)..]; }

3.2 String Processing Optimization

// ❌ Bad example: Substring allocates new string string part = text.Substring(0, 10);

// ✅ Good example: AsSpan has no allocation ReadOnlySpan<char> part = text.AsSpan(0, 10);

3.3 Using with stackalloc

public void ProcessSmallBuffer() { // Allocate small buffer on Stack (no Heap allocation) Span<byte> buffer = stackalloc byte[256]; FillBuffer(buffer); }

  1. ArrayPool

Reduces GC pressure by reusing large arrays.

4.1 Basic Usage

namespace MyApp.Services;

public sealed class DataProcessor { public void ProcessLargeData(int size) { // Rent array (minimize Heap allocation) var buffer = ArrayPool<byte>.Shared.Rent(size);

    try
    {
        // Use buffer (only use up to requested size)
        ProcessBuffer(buffer.AsSpan(0, size));
    }
    finally
    {
        // Must return
        ArrayPool&#x3C;byte>.Shared.Return(buffer);
    }
}

}

4.2 clearArray Option

// Initialize before returning when handling sensitive data ArrayPool<byte>.Shared.Return(buffer, clearArray: true);

  1. ObjectPool

Reuses expensive objects.

namespace MyApp.Services;

using Microsoft.Extensions.ObjectPool;

public sealed class HeavyObjectProcessor { private readonly ObjectPool<HeavyObject> _pool;

public HeavyObjectProcessor()
{
    var policy = new DefaultPooledObjectPolicy&#x3C;HeavyObject>();
    _pool = new DefaultObjectPool&#x3C;HeavyObject>(policy, maximumRetained: 100);
}

public void Process()
{
    var obj = _pool.Get();

    try
    {
        obj.DoWork();
    }
    finally
    {
        _pool.Return(obj);
    }
}

}

  1. Memory

Unlike Span, can be stored in fields or used in async methods.

public sealed class AsyncProcessor { private Memory<byte> _buffer;

public AsyncProcessor(int size)
{
    _buffer = new byte[size];
}

// Memory&#x3C;T> can be used in async methods
public async Task ProcessAsync()
{
    await FillBufferAsync(_buffer);
    ProcessData(_buffer.Span);
}

}

  1. Required NuGet Package

<ItemGroup> <PackageReference Include="Microsoft.Extensions.ObjectPool" Version="9.0.*" /> </ItemGroup>

  1. Important Notes

⚠️ Span Constraints

  • Span<T> , ReadOnlySpan<T> cannot be used with async-await

  • Cannot be boxed (ref struct)

  • Cannot be stored as class field (use Memory)

  • Cannot be captured in lambdas/closures

⚠️ ArrayPool Return Required

  • Arrays rented with Rent() must be returned with Return()

  • Use try-finally pattern

  • Memory leak occurs if not returned

⚠️ Rented Size vs Actual Size

// Array larger than requested may be returned var buffer = ArrayPool<byte>.Shared.Rent(100); // buffer.Length >= 100 (not exactly 100)

// Use only requested size when actually using ProcessBuffer(buffer.AsSpan(0, 100));

  1. References
  • Span - Microsoft Docs

  • ArrayPool - Microsoft Docs

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

converting-html-css-to-wpf-xaml

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

publishing-wpf-apps

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

managing-styles-resourcedictionary

No summary provided by upstream source.

Repository SourceNeeds Review