ZGC and Shenandoah — Sub-Millisecond Pauses Through Concurrent Compaction
Fast recall
Quick revision
Core answer
-XX:MaxGCPauseMillis=200 can deliver.Whether you understand HOW concurrent compaction is possible — load barriers, colored pointers, forwarding pointers — not just that pauses are short
Thinking ZGC eliminates GC overhead entirely (it doesn't — it shifts the cost from pause time to background CPU work)
Explain why ZGC's heap-size-independent pause time matters for very large heaps and how generational ZGC (Java 21+) closed the throughput gap
Interview-ready guide
Interview answer
ZGC and Shenandoah achieve sub-millisecond pause times by solving the hardest problem in garbage collection: concurrent compaction. Every collector before them required stopping application threads to safely move objects in memory. ZGC and Shenandoah eliminate that requirement using load barriers and pointer indirection.
The core mechanism:
- A small read barrier — a few CPU instructions — runs on every pointer load
- The barrier transparently redirects reads to the current location of moved objects
- The GC can relocate objects in the background while the application keeps running
ZGC specifically:
- Uses colored pointers — extra metadata bits embedded in 64-bit references
- The load barrier checks these bits and triggers GC bookkeeping when needed
- Pauses scale with the number of threads, not heap size — same pause on 1GB and 16TB heaps
- Production-ready since Java 15; generational ZGC since Java 21 closed the throughput gap
Shenandoah specifically:
- Uses Brooks pointers — a forwarding pointer in every object header
- Similar pause-time characteristics to ZGC; different algorithm; Red Hat's choice
Trade-offs to be honest about:
- 5-15% additional CPU overhead for the load barrier and concurrent work
- Modest memory overhead — about 3% for ZGC's colored pointer metadata
- For workloads where G1 already meets the SLA, ZGC just costs CPU without business value
When to choose them:
- p99 latency requirements stricter than G1's 200ms target — algorithmic trading, real-time bidding, ad tech
- Very large heaps where G1's mixed collection pauses become significant
- After diagnosing that GC pauses are the dominant tail latency contributor, not a guess
In an interview, I'd emphasize the diagnostic step — measure first, switch second. ZGC is a real improvement, but it is not free, and chasing it without data wastes CPU.
ZGC and Shenandoah — Sub-Millisecond Pauses Through Concurrent Compaction
Direct Answer
ZGC and Shenandoah achieve sub-millisecond pauses by performing all GC work — including compaction — concurrently with application threads. ZGC (Oracle, production-ready in Java 15) uses colored pointers and load barriers to relocate objects without stopping the world. Shenandoah (Red Hat, production-ready in Java 15) uses Brooks pointers (forwarding pointers in object headers) for the same goal. Both target heaps from a few hundred MB to multiple TB with pauses under 10ms — and typically under 1ms. The trade-off is 5-15% additional CPU overhead and modest extra memory for the relocation metadata. Use them when p99 latency requirements are stricter than what G1's -XX:MaxGCPauseMillis=200 can deliver.
Common Mistakes & Pitfalls
Thinking ZGC eliminates GC overhead entirely (it doesn't — it shifts the cost from pause time to background CPU work)
Check your understanding
Answer these without looking back at the article.
- What is generational ZGC and why was it added to the JVM?
- How do colored pointers in ZGC interact with x86-64 virtual memory?
- What is the difference between a load barrier and a write barrier?
- How would you decide between ZGC and Shenandoah for a new service?
Related interview prep categories
2Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.