Understanding stackalloc in C# for High Performance
This article explains how the stackalloc keyword enables
stack-based memory allocation in C# to achieve optimal runtime
performance. It covers the mechanics of allocating temporary memory
directly on the execution stack, how it bypasses garbage collection
overhead, and how modern C# features like Span<T>
make this low-level optimization both safe and accessible for
high-throughput applications.
What Is stackalloc?
In standard C# execution, reference types and traditional arrays are allocated on the managed heap. While the managed heap is flexible and dynamically sized, allocating objects there incurs overhead: memory must be tracked, cleared, and eventually reclaimed by the Garbage Collector (GC).
The stackalloc keyword provides an alternative by
allocating a block of memory directly on the call stack. The allocated
memory exists only for the lifetime of the current method execution and
is immediately reclaimed when the method returns, without any
intervention from the GC.
How stackalloc Works with Span<T>
Historically, using stackalloc required an
unsafe code block and raw pointer arithmetic
(int* buffer = stackalloc int[100];). Modern C# (version
7.2 and later) allows stackalloc to be assigned directly to
a Span<T> or ReadOnlySpan<T>
without marking code as unsafe:
Span<byte> buffer = stackalloc byte[256];Because Span<T> is a ref struct that
is itself restricted to the stack, the compiler guarantees that the
memory reference cannot outlive the stack frame in which it was created.
This eliminates memory safety hazards such as dangling pointers while
retaining the performance benefits of raw memory access.
Why stackalloc Delivers High Performance
- Zero Garbage Collection Overhead: Heap allocations eventually trigger GC cycles, which consume CPU cycles and can cause application pauses. Stack-allocated memory requires no garbage collection tracking, entirely removing GC pressure for temporary buffers.
- Instant Allocation and Deallocation: Allocating memory on the stack is essentially a single CPU instruction that adjusts the stack pointer. Deallocation occurs automatically when the stack frame unwinds upon method exit.
- Improved Cache Locality: Stack memory is frequently accessed and typically resides in the CPU's L1 or L2 cache. Reusing this active memory area results in faster read and write speeds compared to accessing fragmented regions of the managed heap.
Best Practices and Safety Considerations
While stackalloc is powerful, the call stack has a
strictly limited size (typically 1 MB on Windows threads by default).
Attempting to allocate too much memory on the stack will cause a fatal
StackOverflowException, which cannot be caught or recovered
from in .NET.
To use stackalloc safely:
- Use it exclusively for small, short-lived buffers (typically a few hundred bytes to a few kilobytes).
- For variable-length data, implement a threshold check. If the
required buffer exceeds a safe size (e.g., 512 or 1024 bytes), fall back
to
ArrayPool<T>.Sharedto prevent stack exhaustion.