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 = -Xmx for 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:ConcGCThreads if 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.