What is G1 GC?
G1 replaced Parallel GC as the default because it provides predictable pauses. The name "Garbage First" means: collect regions with the most garbage first (maximum efficiency pe...
Junior Level
G1 (Garbage First) — the default garbage collector in Java (since Java 9).
G1 replaced Parallel GC as the default because it provides predictable pauses. The name “Garbage First” means: collect regions with the most garbage first (maximum efficiency per cycle).
Main idea: Divides Heap into regions and collects the “dirtiest” ones first.
Simple analogy: Cleaning a house — you clean the dirtiest rooms first, not the entire house at once.
Advantages:
- Predictable pauses (configurable)
- Works well on Heap from 4 GB to tens of GB. Above 32 GB, Compressed OOPs are disabled — this affects all GCs, not just G1.
- Balance between speed and pauses
Middle Level
G1 Regions
Heap split into 2048 regions (1-32 MB each)
Region types:
Eden — new objects
Survivor — survivors
Old — long-lived
Humongous — large objects (> 50% of region)
Free — free
Remembered Sets (RSet)
Each region stores: which OTHER regions reference it
Why:
→ During Young GC, no need to scan entire Old Gen
→ Only regions with references to Young are scanned
Remembered Sets (RSet) — data structure for each region that
tracks incoming references from OTHER regions.
Allows G1 to avoid scanning entire Heap.
Work Cycle
1. Young GC (STW) — copying young objects
2. Concurrent Marking — background Old Gen marking
3. Mixed GC — Young + dirtiest Old regions
Goal: fit within MaxGCPauseMillis
Tuning
-XX:MaxGCPauseMillis=200 # Target pause
-XX:InitiatingHeapOccupancyPercent=45 # Old GC threshold
Senior Level
Collection Set (CSet)
Set of regions to clean in the current cycle
Collection Set (CSet) — set of regions selected for collection
in the current cycle. G1 selects regions with the most garbage.
Young GC:
→ CSet = all Young regions
Mixed GC:
→ CSet = Young + dirtiest Old regions
→ G1 selects to fit within MaxGCPauseMillis
Evacuation Failure
Not enough space in target regions when copying live objects
→ To-space exhausted
→ Full GC (STW!)
Evacuation Failure (To-space exhausted) — when G1 runs out of
space to copy live objects. Fallback to Full GC — long pause.
Causes:
- Fragmentation
- Too many live objects
Solution: increase Heap or decrease MaxGCPauseMillis
String Deduplication
-XX:+UseStringDeduplication
G1 finds identical char[] in different Strings
→ Collapses into one reference
→ 5-10% Heap savings
Works only for Strings created via new String() or concatenation.
Strings from literal pool are already deduplicated. Greatest effect for
applications with many duplicate strings.
Generational ZGC vs G1
G1: pauses 20-200 ms, good throughput
ZGC: pauses < 1 ms, -5-10% throughput
Choice: SLA < 10 ms → ZGC, otherwise G1
Generational ZGC requires Java 21+. On Java 17, use G1.
Best Practices
- Don’t fix -Xmn for G1 (loses adaptivity)
- Don’t set MaxGCPauseMillis too low (< 50 ms)
- Tune IHOP for your Promotion Rate
- Humongous → increase G1HeapRegionSize
- Enable String Deduplication for memory savings
- Monitor To-space exhausted
Senior Summary
- G1 = regional, adaptive GC
- RSet = Young GC optimization
- CSet = selects dirtiest regions
- SATB = concurrent marking algorithm
- Evacuation Failure = worst case scenario
- Don’t fix Young Gen — G1 is adaptive
- MaxGCPauseMillis = main tuning lever
Interview Cheat Sheet
Must know:
- G1 divides Heap into 2048 regions (1-32 MB); types: Eden, Survivor, Old, Humongous, Free
- RSet (Remembered Set): each region stores which other regions reference it → Young GC doesn’t scan entire Heap
- CSet (Collection Set): regions selected for collection in current cycle; G1 selects the “dirtiest”
- G1 cycle: Young GC (STW) → Concurrent Marking → Mixed GC (Young + dirty Old regions)
- Evacuation Failure (To-space exhausted): no space to copy live objects → Full GC (STW!)
- SATB (Snapshot-At-The-Beginning): concurrent marking; Floating Garbage — objects that became garbage after snapshot
- String Deduplication (
-XX:+UseStringDeduplication): G1 collapses identicalchar[]in String → 5-10% Heap savings
Common follow-up questions:
- Why shouldn’t MaxGCPauseMillis be set too low (< 50 ms)? — G1 cannot fit → Evacuation Failure → Full GC
- What is IHOP (InitiatingHeapOccupancyPercent)? — Old Gen threshold (default 45%) at which G1 starts Concurrent Marking; tune for your Promotion Rate
- What to do about Humongous Objects? — Increase
-XX:G1HeapRegionSize(e.g., 16m or 32m) so objects aren’t considered Humongous - Why shouldn’t
-Xmnbe fixed for G1? — G1 adaptively changes Young Gen to achieve MaxGCPauseMillis; fixing breaks adaptivity
Red flags (DO NOT say):
- “G1 scans entire Old Gen during Young GC” — RSet optimization: only regions with references to Young are scanned
- “I’ll set MaxGCPauseMillis=10 ms for maximum speed” — G1 cannot fit → To-space exhausted → Full GC
- “String Deduplication saves memory on String Pool strings” — works only for
new String()and concatenation; pool strings are already deduplicated
Related topics:
- [[8. What are generations in GC]]
- [[12. What GC algorithms exist]]
- [[14. What is ZGC]]
- [[16. What is stop-the-world]]
- [[10. What is Old Generation (Tenured)]]