Skip to main content
Course/Module 11/Topic 1 of 4Advanced

Memory Management & Garbage Collection

Deep dive into .NET memory management — understand the garbage collector, memory allocations, and how to write memory-efficient code.

55 minBy Priygop TeamLast updated: Feb 2026

How .NET Garbage Collection Works

The .NET Garbage Collector (GC) automatically manages memory allocation and deallocation. It uses a generational model with 3 generations: Gen 0 (short-lived objects — collected most frequently, typically sub-millisecond pauses), Gen 1 (buffer between short and long-lived — collected less often), and Gen 2 (long-lived objects — collected infrequently but with longer pauses). Objects start in Gen 0 and are promoted to higher generations if they survive collection. The Large Object Heap (LOH) stores objects >= 85,000 bytes separately — LOH collection is expensive and causes fragmentation. GC modes: Workstation GC (optimized for responsive desktop apps, smaller heap), Server GC (optimized for throughput, parallel collection on multiple threads, larger heap per core). In .NET 8+, GC has DPAD (Dynamic Physical Address Partitioning) for better NUMA-aware allocation. Understanding GC helps you write code that minimizes allocation pressure and avoids GC pauses.

Reducing Memory Allocations

  • Span<T> and Memory<T>: Work with contiguous memory without heap allocation — parse strings, process buffers without creating copies. Stackalloc for small arrays
  • ArrayPool<T>: Rent and return arrays instead of allocating new ones — ArrayPool<byte>.Shared.Rent(1024). Dramatically reduces Gen 0 GC pressure
  • StringBuilder: Use for string concatenation in loops — string + string creates new objects each time. StringBuilder modifies in-place
  • ValueTask<T>: Use instead of Task<T> when operations often complete synchronously — avoids Task allocation overhead for hot paths
  • Object Pooling: ObjectPool<T> for expensive-to-create objects — database connections, HttpClient, serializers. Create once, reuse many times
  • Record Structs: Use readonly record struct for small, immutable value types — stack-allocated, no GC pressure. Perfect for DTOs in hot paths
  • String Interning: Use string.Intern() for frequently repeated strings — stores one copy shared across references. Reduces duplicate string allocations

Memory Profiling Tools

  • dotnet-counters: Real-time monitoring — GC collection counts, allocation rate, heap size, thread pool utilization. Lightweight, production-safe
  • dotnet-dump: Capture and analyze memory dumps — find memory leaks by examining object roots, large objects, and reference chains
  • dotnet-trace: Collect performance traces with ETW events — analyze GC events, allocations, exceptions, and thread activity
  • Visual Studio Diagnostic Tools: Memory Usage profiler — take heap snapshots, compare allocations between snapshots, identify leaking types
  • BenchmarkDotNet: Micro-benchmarking framework — measures execution time, memory allocation, and GC collections per operation with statistical rigor
  • JetBrains dotMemory: Commercial profiler with visual heap analysis — sunburst diagrams, retention paths, real-time allocation tracking
Chat on WhatsApp
Priygop - Leading Professional Development Platform | Expert Courses & Interview Prep