Interview Prep Zoneby CuriouserLabs

Question 2 of 5 · senior level

How does generational garbage collection work, and why are most collections 'minor'?

🎤 Say this first

The heap is split by object age because of the weak generational hypothesis: most objects die young. New objects go to Eden; when it fills, a minor GC copies the few live objects to a survivor space and discards the rest wholesale — cost is proportional to survivors, not garbage. Objects surviving several cycles are promoted to the old generation, which is collected less often with more expensive algorithms (mark-compact / concurrent marking).

The full picture

🎬 Generational garbage collection

1 / 5
Eden — new objects born hereSurvivor 0Survivor 1Old generation Copying live objects (not sweeping dead ones) is what makes minor GCs fast when most objects die young.

The heap is split by object age: Eden + two survivor spaces (young generation) and the old generation. New objects are allocated in Eden — allocation is just a pointer bump.

Eden → survivor ping-pong → promotion → old-gen collection.

Why copying wins for the young gen: a copying collector touches only live objects. If 95% of Eden is dead, a minor GC moves 5% and resets the allocation pointer — allocation itself stays a bump-the-pointer operation (with per-thread TLABs so threads don't contend). The old generation can't use pure copying (too much live data), so collectors there mark live objects and either compact (Parallel, G1 mixed collections) or handle it concurrently in regions (G1, ZGC, Shenandoah).

  • GC roots — thread stacks, static fields, JNI handles: tracing starts here; anything unreachable is garbage (reference counting is not used — cycles).
  • Card table / remembered sets — track old→young pointers so a minor GC doesn't scan the whole old gen.
  • Premature promotion — survivor spaces too small or allocation spikes push short-lived objects into old gen, turning cheap minor GCs into expensive old-gen churn. A classic tuning finding.
  • Stop-the-world — even 'concurrent' collectors have brief pauses; young collections in G1/Parallel are fully STW but usually a few ms.

🔄 Likely follow-up questions

  • What are soft/weak/phantom references and a real use for each?
  • What is a humongous allocation in G1 and why is it painful?
  • How do TLABs make multi-threaded allocation scale?