In this lesson, you will learn how to fine-tune the .NET Garbage Collector to balance background memory reclamation with your application’s latency requirements.
The Trade-off: Throughput vs. Latency
By default, the .NET Workstation and Server GC use "Background GC" (previously known as Concurrent GC). This allows the collector to perform most of its work on a separate, dedicated thread, permitting your application threads to continue executing while the heap is being scanned.
While this drastically reduces "Stop-the-World" pauses, it comes at a cost: Background GC consumes CPU cycles that would otherwise be available to your application. If your application has strict P99 latency requirements, you may need to adjust how aggressively the GC interacts with your workload.
Configuring via runtimeconfig.json
You control these settings primarily through the runtimeconfig.json file. The most critical toggle is System.GC.Concurrent. When enabled, the GC performs most of its collection work concurrently with application threads. If you disable it, the GC will pause all application threads during the entire collection process.
{
"runtimeOptions": {
"configProperties": {
"System.GC.Concurrent": true,
"System.GC.Server": true
}
}
}
When to Adjust Settings
If your application experiences jittery latency spikes, it might be due to "GC Stall." A GC Stall happens when the application allocates memory faster than the background GC can reclaim it. When the system hits a high-memory threshold, it is forced to pause the application threads to finish the collection immediately.
If you are running in a containerized environment with strict CPU limits, background GC threads might fight for CPU time with your worker threads. In such cases, you should:
- Monitor Stall Times: Use the diagnostic tools we covered in lesson 15 to measure if your pauses are caused by background GC contention.
- Experiment with Server GC: If you have high-throughput requirements, ensure
System.GC.Serveris set totrue, which optimizes the GC for multi-core scaling. - Analyze CPU Pressure: If background GC threads are starved, reduce the frequency of collections by optimizing your data-oriented design (lesson 2) to reduce allocations, rather than just forcing the GC to run differently.
Key Takeaway: Concurrent GC minimizes pause times, but you must monitor GC stall metrics to ensure that background reclamation tasks are not being starved of the CPU resources required to keep your application responsive.