Java 25 ships Generational ZGC as the sole ZGC flavor with LTS support, making it a good time to evaluate this concurrent garbage collector. Benchmarks comparing ZGC and G1 on a Quarkus microservice show nearly identical latencies up to p99, but ZGC dramatically reduces p999 and p9999 tail latencies by eliminating GC pauses (longest pause ~50 microseconds vs. 20+ ms with G1). However, ZGC is not universally superior: under CPU-bound workloads with very high allocation rates (~30 GB/sec), ZGC can suffer allocation stalls when concurrent GC threads can't keep up, leading to worse latencies than G1. The key takeaway is that ZGC excels at reducing tail latencies for typical microservice workloads with default settings, but CPU-bound applications may be better served by G1. Allocation stalls can be monitored via the ZAllocationStall JFR event.
Sort: