Why does the .NET garbage collector use generations?
Quick Answer
Generational collection is based on the observation that most objects die young. New objects go in Gen 0, which is small and collected often and fast. Survivors are promoted to Gen 1, then Gen 2 (long-lived). The expensive full collection (Gen 2 + Large Object Heap) then runs rarely.
The whole design rests on the generational hypothesis — the vast majority of objects are short-lived, like local variables and temporaries. So new objects go into Gen 0, which is small, and collecting it is quick because almost everything in there is already garbage. The few objects that survive get promoted to Gen 1, then Gen 2, which is where the long-lived stuff like caches and singletons ends up. A full Gen 2 collection is the expensive one, and it only runs occasionally. Large objects over about 85KB skip straight to the Large Object Heap.
- Gen 0 + Gen 1 are the “ephemeral” segment — collecting them is cheap because they're small and mostly garbage.
- Gen 2 holds static data, caches, long-lived services; a Gen 2 collection is a full GC and can pause more.
- Objects ≥ ~85,000 bytes go straight on the Large Object Heap, collected with Gen 2, and (by default) not compacted — LOH fragmentation is a real issue.
- Server GC vs Workstation GC, background GC, and pinning all affect pause behaviour.