Java Garbage Collection: GC Roots, Mark-and-Sweep, and Generational GC
Fast recall
Quick revision
Core answer
Whether you understand object lifecycle, what keeps an object alive, and how the JVM avoids scanning the whole heap on every GC cycle
Confusing 'garbage collected' with 'immediately freed' — GC is non-deterministic, and calling System.gc() is only a hint. Also confusing Young GC (minor) and Full GC (major) costs.
Name concrete collectors (G1GC, ZGC, Shenandoah), explain stop-the-world pauses, describe the remembered set / card table used to track old-to-young references, and mention GC tuning flags like -Xmx, -Xms, -XX:+UseG1GC
Interview-ready guide
Interview answer
The JVM determines what's alive by tracing from GC roots — thread stacks, static fields, JNI references. Anything reachable through a reference chain is alive; everything else is eligible for collection.
Generational collection:
- Most objects die young — Eden fills up, minor GC copies survivors to a Survivor space, frees Eden in bulk by resetting a pointer
- Typically 90%+ of Eden is already dead by the time minor GC runs — very fast
- Objects surviving enough minor GC cycles are promoted to Old Generation
Card table (why minor GC stays fast):
- Old-to-young references tracked by a card table — each byte covers a 512-byte region of old gen
- When an old object's reference changes, the card is marked dirty
- Minor GC only scans dirty cards, avoiding a full old-gen scan
Modern collectors:
- G1GC (default since Java 9) — region-based, targets predictable pause times via
-XX:MaxGCPauseMillis=200 - ZGC — sub-millisecond pauses regardless of heap size using colored pointers; higher CPU overhead
- Shenandoah — similar goals to ZGC, different implementation; available in OpenJDK
Tuning basics:
System.gc()is a hint, not a command — collection timing is non-deterministic- Set
-Xmsequal to-Xmxin production — prevents heap resize pauses
I recommend G1 as the default and switching to ZGC only when you need consistent sub-millisecond pauses and can accept the extra CPU overhead.
Java Garbage Collection: GC Roots, Mark-and-Sweep, and Generational GC
Direct Answer
The JVM periodically traces live objects starting from GC roots (stack variables, static fields, JNI references), marks everything reachable as live, then sweeps or compacts unreachable objects. Modern JVMs use generational collection — splitting the heap into Young and Old generations — because most objects die young.
Common Mistakes & Pitfalls
Confusing 'garbage collected' with 'immediately freed' — GC is non-deterministic, and calling System.gc() is only a hint. Also confusing Young GC (minor) and Full GC (major) costs.
Check your understanding
Answer these without looking back at the article.
- What is the difference between G1GC and ZGC?
- How do you diagnose a memory leak in a Java application?
- What is a stop-the-world pause and how do concurrent collectors reduce it?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.