Choosing
- G1: balanced latency/throughput for heaps 4–64GB; predictable pauses.
- ZGC: sub-10ms pauses on large heaps; great for latency-sensitive APIs; slightly higher CPU.
Baseline flags
- G1:
-XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+ParallelRefProcEnabled -XX:+AlwaysPreTouch - ZGC:
-XX:+UseZGC -XX:+ZGenerational -XX:+AlwaysPreTouch - Set
-Xms = -Xmxfor stable footprint; size heap from prod RSS data.
Metrics to watch
- Pause p95/p99, GC CPU %, allocation rate, remembered set size (G1), heap occupancy.
- STW reasons: promotion failure, humongous allocations (G1), metaspace growth.
Common fixes
- Reduce humongous allocations: avoid giant
byte[]; use chunked buffers. - Lower pause targets only after measuring; avoid over-constraining
MaxGCPauseMillis. - Cap thread counts:
-XX:ParallelGCThreads,-XX:ConcGCThreadsif CPU saturated. - For ZGC, ensure kernel pages hugepage-friendly; watch NUMA pinning.
Checklist
- Heap sized from live data;
-Xms = -Xmx. - GC logs on (JDK 17+):
-Xlog:gc*:tags,level,time,uptime:file=gc.log:utctime,filesize=20M,files=10 - Dashboards for pause/CPU/allocation.
- Load test changes before prod; compare pause histograms release to release.