The generational hypothesis behind young/old generation splits, minor vs major GC, mark-sweep-compact, and what actually counts as a GC root.
Published September 23, 2026
Empirically, in most applications, most objects die young — a request-scoped object, a loop's temporary variable, an intermediate stream result. Long-lived objects (caches, singletons, connection pools) are comparatively rare. The JVM's heap is deliberately split into generations to exploit this pattern: collect the young generation frequently and cheaply (most of it is garbage, so a collection reclaims a lot fast), and collect the old generation rarely and expensively (it's mostly still-live data, so scanning it often would be wasted effort).
[ Eden ] [ S0 ] [ S1 ] <- Young Generation
[ Old Generation ]
New objects are allocated in Eden. When Eden fills up, a Minor GC runs: live objects in Eden are copied into one of the two Survivor spaces (S0/S1 — only one is "active" at a time; the other stays empty until the next collection). Each time an object survives a Minor GC, its age counter increments; after surviving enough collections (the survival threshold, tunable), it gets promoted to the old generation — the assumption being that anything that's survived this many young-gen collections is probably going to live a while longer, so it's cheaper to stop re-copying it every cycle.
This cost asymmetry is exactly why GC tuning (see GC Tuning & Diagnostics) so often focuses on avoiding unnecessary promotions and Full GCs — a young-gen-heavy allocation pattern that rarely needs a Full GC is dramatically cheaper than one that promotes aggressively and triggers frequent old-gen collections.
Three phases, run in sequence during a collection:
Compaction specifically is what prevents fragmentation — without it, a heap could have plenty of total free space scattered in small, non-contiguous chunks, none large enough to satisfy a new allocation request, even though the sum of free space would technically be sufficient.
An object is "live" if it's reachable, by some chain of references, from a GC root — anything not reachable from a root, no matter how large or recently created, is garbage. GC roots include:
Understanding GC roots precisely is what makes heap-dump analysis (see GC Tuning & Diagnostics) tractable — a leak-suspect report works backward from a suspiciously large object, finding the dominator chain of references back to a GC root, which is usually where the actual leak-causing code lives.
Q: Why two Survivor spaces instead of one? A: A Minor GC needs somewhere to copy both the objects currently in the active Survivor space (that haven't been promoted yet) and the newly-surviving objects from Eden, without overwriting either set mid-collection — using two spaces and alternating which one is "active" (a copying collector technique) avoids needing a separate temporary buffer, and as a side effect, it also naturally compacts the young generation on every single Minor GC.
Q: Does every GC algorithm use mark-sweep-compact exactly as described? A: Mark-and-sweep (with or without compaction) is the conceptual baseline nearly every collector builds on, but modern collectors (see Modern Garbage Collectors) add region-based collection, concurrent marking, or incremental/parallel phases on top of this baseline to reduce pause times — the mark/sweep/compact vocabulary still applies, but the how differs significantly by collector.
Q: If an object is referenced only by another garbage object, is it also garbage? A: Yes — reachability is transitive from GC roots. If object A is garbage (unreachable from any root) and A is the only thing referencing object B, then B is also unreachable (nothing traces a live path to it) and gets collected in the same pass, even though nothing explicitly marked B as garbage directly.
Q: Why does the survival threshold exist instead of promoting every object that survives even one Minor GC? A: Promoting too eagerly fills the old generation with objects that might still die soon after, which wastes old-gen space and triggers more (expensive) old-gen collections than necessary — requiring several survived cycles before promotion is a bet that objects surviving that long are genuinely likely to be long-lived, filtering out the "survived by coincidence, still short-lived" cases.