Overview
The .NET runtime provides a generational, concurrent, and compacting garbage collector (GC) that automatically manages the allocation and release of memory for managed objects.
using System;
class Program
{
static void Main()
{
var obj = new object(); // allocation
// obj becomes eligible for collection after this method exits
}
}Generations
.NET GC organizes objects into three generations:
- Gen 0 – short‑lived objects
- Gen 1 – objects that survived a Gen 0 collection
- Gen 2 – long‑lived objects
Promotions occur automatically based on survivorship. Gen 2 is collected less frequently, reducing pause times for long‑lived data.
Large Object Heap (LOH)
Objects larger than 85,000 bytes are allocated on the LOH. The LOH is collected only during full (Gen 2) collections and may become fragmented.
- Reuse large buffers instead of constantly reallocating.
- Prefer
ArrayPool<T>for temporary large arrays. - Consider
Span<T>andMemory<T>to avoid allocations.
Pinning & Handles
Pinning prevents the GC from moving an object. Use it sparingly to avoid fragmentation.
fixed (byte* p = buffer)
{
// p is a pinned pointer to the array
}
For advanced scenarios, explore GCHandle.
GC Modes
The runtime supports several GC modes, controlled by System.GCSettings or environment variables:
- Workstation – optimized for client apps (default).
- Server – optimized for multi‑processor servers.
- Background – concurrent collection for Gen 2.
Switch modes with dotnet run --gc-server true or set COMPlus_gcServer=1.
Diagnostics & Tools
Use these tools to analyze GC behavior:
- dotnet-counters – real‑time metrics.
- dotnet-trace – ETW tracing.
- GCLog (EventSource) – detailed logs.
Example command to monitor GC pauses:
dotnet-counters monitor -p <pid> System.Runtime