GC suspension
Before most collections the runtime must suspend all managed threads. The time this takes is the suspension time.
Before most collections the runtime must suspend all managed threads. The time this takes is the suspension time.
Managed threads are stopped at safe points in their code. Threads in native code are marked so that they cannot return to managed code during the collection. A thread that does not reach a safe point quickly (a long tight loop, a long operation) delays the whole collection while the others wait.
In .NET traces, suspension time is reported separately from the collection time. GC Doctor charts it so that a long pause can be attributed to the collector or to the wait before it. Long suspensions often come from hot loops, thread pool starvation or an overloaded machine.
Background GC
Concurrent collection of generation 2, which lets gen 0 and gen 1 collections run in the meantime.
A blocking gen 2 collection stops all managed threads for a long time. With background GC (on by default, setting System.GC.Concurrent), a dedicated thread marks gen 2 concurrently with the application. If gen 0 fills up in the meantime, a foreground collection of the ephemeral generations briefly suspends the threads, runs, then lets the background collection continue.
Only a gen 2 collection that cannot be a background one, for example when it is induced as blocking or when memory is very low, is a long pause. Background GC reduces pause times at the cost of some CPU and memory. GC Doctor labels .NET collections as background or blocking, which explains why a gen 2 collection did or did not cause a long pause.
Official documentation: Background garbage collection (Microsoft Learn)
Generations (gen 0, 1, 2)
The .NET managed heap is divided by age: gen 0 for new objects, gen 1 as a buffer, gen 2 for long-lived objects.
A collection of generation N also collects all younger generations: a gen 1 collection includes gen 0, and a gen 2 collection, called full or blocking, covers the whole heap including the large object heap. Survivors of gen 0 are promoted to gen 1, survivors of gen 1 to gen 2. Gen 0 and gen 1 are the ephemeral generations; they are small and quick to collect.
A healthy application shows many gen 0 collections, fewer gen 1 and rare gen 2. A high share of gen 2 collections, or gen 1 collections that promote a lot, means objects survive longer than they should: caches, bursts of allocation, objects kept alive by finalizers. The GC events of a .nettrace give the generation and the reason of each collection; GC Doctor charts them per generation.
Official documentation: Fundamentals of garbage collection (Microsoft Learn)
GC suspension