Java

Modern Java GC: G1 vs. ZGC - Choosing the Right Collector

Explore modern Java garbage collection. Learn the architectural differences between the G1 (Garbage First) and ZGC (Z Garbage Collector) and how to tune them for your workload.

Sachin Sarawgi·April 20, 2026·2 min read
#java#garbage-collection#jvm-tuning#performance#zgc

Modern Java Garbage Collection: G1 vs. ZGC

The days of massive "stop-the-world" pauses in Java are largely over. With the introduction of modern collectors like G1 and ZGC, Java can now handle heaps from a few gigabytes to several terabytes with sub-millisecond pause times.

1. G1 GC (Garbage First)

The default collector since Java 9. It is a regional, generational collector.

  • How it works: It divides the heap into equal-sized regions. It prioritizes collecting regions with the most garbage (hence "Garbage First").
  • Pros: Great balance between throughput and latency. You can set a goal pause time (e.g., -XX:MaxGCPauseMillis=200).
  • Best for: Most standard business applications with heap sizes up to 32GB.

2. ZGC (Z Garbage Collector)

Introduced as a production-ready feature in Java 15. It is a scalable, low-latency collector.

  • How it works: It performs almost all its work concurrently with the application threads. It uses colored pointers and load barriers to track object movement without stopping the world.
  • Pros: Guaranteed pause times of less than 1ms, regardless of heap size. It can handle heaps up to 16TB.
  • Cons: Slightly lower throughput (CPU overhead) compared to G1.
  • Best for: Low-latency trading systems, real-time data processing, and huge memory-intensive caches.

3. The Generational ZGC (Java 21+)

The latest evolution. By introducing generations (Young/Old) to ZGC, Java 21 has significantly improved its efficiency, making it the most powerful GC in Java's history. It maintains sub-millisecond latency while drastically reducing CPU overhead for short-lived objects.

4. How to Choose?

  • Scenario A: You care about maximum throughput and can tolerate 100-200ms pauses.
    • Choice: G1 GC.
  • Scenario B: You need extremely consistent response times (.9 < 10ms$) and have a large heap.
    • Choice: ZGC.
  • Scenario C: You have a small heap (< 2GB) and want the simplest setup.
    • Choice: Serial GC.

5. Key Tuning Parameters

  • G1: -XX:+UseG1GC -XX:MaxGCPauseMillis=200
  • ZGC: -XX:+UseZGC -XX:+ZGenerational (Java 21+)

Summary

Garbage collection is no longer the bottleneck it once was. By choosing G1 for general-purpose workloads or ZGC for low-latency requirements, you can ensure your Java application remains responsive and efficient at any scale.

📚

Recommended Resources

Designing Data-Intensive ApplicationsBest Seller

The definitive guide to building scalable, reliable distributed systems by Martin Kleppmann.

View on Amazon
Kafka: The Definitive GuideEditor's Pick

Real-time data and stream processing by Confluent engineers.

View on Amazon
Apache Kafka Series on Udemy

Hands-on Kafka course covering producers, consumers, Kafka Streams, and Connect.

View Course

Practical engineering notes

Get the next backend guide in your inbox

One useful note when a new deep dive is published: system design tradeoffs, Java production lessons, Kafka debugging, database patterns, and AI infrastructure.

No spam. Just practical notes you can use at work.

Sachin Sarawgi

Written by

Sachin Sarawgi

Engineering Manager and backend engineer with 10+ years building distributed systems across fintech, enterprise SaaS, and startups. CodeSprintPro is where I write practical guides on system design, Java, Kafka, databases, AI infrastructure, and production reliability.

Found this useful? Share it: