Z Garbage Collector (ZGC)

ZGC, or Z Garbage Collector, is a modern garbage collection algorithm introduced in Java 11. It was designed to handle very large heap sizes with extremely low pause times. ZGC aims to keep pause times under 10 milliseconds, even with heaps sized in terabytes.

For beginners, ZGC might sound complicated, but this article breaks it down into simple concepts. We will explain how ZGC works, what makes it different, when to use it, and how to tune it. Since ZGC is one of the newest collectors in the JVM, understanding it can be valuable for working on high-performance or large-scale Java applications.

What is ZGC?

ZGC stands for Z Garbage Collector. It is a low-latency, scalable, and concurrent garbage collector designed for applications that need high performance and minimal interruption.

ZGC focuses on the following goals:

  • Pause times less than 10ms.
  • Handles heaps from a few gigabytes to multiple terabytes.
  • Most of the work happens concurrently, while the application is still running.
  • Designed to reduce stop-the-world (STW) events.

ZGC was introduced as an experimental feature in Java 11 and became stable in Java 15.

How ZGC Works

ZGC uses a few advanced techniques to achieve low pause times and high scalability. Let’s look at the main features of how it works:

1. Region-Based Heap Structure

ZGC divides the heap into multiple colored regions instead of Young and Old generations. These regions include:

  • Allocated regions: Where new objects are stored.
  • Relocation regions: Where live objects are moved.
  • Remapped regions: Used after pointer updates.

This region-based approach helps ZGC manage memory more flexibly.

2. Colored Pointers

ZGC uses colored pointers (special bits in object references) to track the state of objects. These help ZGC avoid long STW events by allowing it to update object references concurrently.

The pointer colors include:

  • Marked: The object has been marked alive.
  • Remapped: The pointer has been updated after relocation.
  • Finalizable: The object needs finalization.

3. Concurrent Phases

Most of ZGC’s garbage collection phases run concurrently with the application, meaning they do not pause the application for long. These include:

  • Concurrent Marking: Finds live objects.
  • Concurrent Relocation: Moves live objects to new regions.
  • Concurrent Remapping: Updates references to the moved objects.

4. Pause Phases

Even though ZGC is mostly concurrent, it has very short pause phases:

  • Mark Start: Quickly identifies root references.
  • Relocation Start: Starts object movement.
  • Remap Start: Begins updating pointers.

Each of these pauses is designed to take less than 1ms to 2ms, keeping total pause time very low.

Z Garbage Collector (ZGC)

ZGC Collection Process

Here’s how ZGC performs garbage collection:

  1. Allocation:
    Objects are created and stored in available regions. When space runs low, ZGC starts a new GC cycle.
  2. Mark Phase (Concurrent):
    ZGC marks all live objects. This happens while the application continues running.
  3. Relocate Phase (Concurrent):
    Live objects are moved to new regions. ZGC avoids fragmentation during this phase.
  4. Remap Phase (Concurrent):
    All references to relocated objects are updated.

Because these phases run mostly in the background, ZGC achieves ultra-low latency.

ZGC Tuning Parameters

ZGC is simple to configure. Here are the common JVM options:

  • -XX:+UseZGC: Enables the Z Garbage Collector.
  • -Xms and -Xmx: Set initial and maximum heap size.
  • -XX:MaxHeapSize=<n>: Specifies max heap size.
  • -XX:+ZUncommit: Allows unused memory to be returned to the OS.
  • -XX:ZUncommitDelay=<n>: Time to wait before releasing memory (in seconds).

ZGC does not require generation tuning, survivor ratios, or other traditional settings.

Advantages of ZGC

ZGC offers several benefits, especially for large applications that require smooth performance:

  • Pause times under 10ms, even with large heaps.
  • Scales well from gigabytes to terabytes of heap memory.
  • Concurrent execution minimizes impact on application threads.
  • No manual tuning of generations or regions is needed.
  • Reduces memory fragmentation through relocation.

Limitations of ZGC

While ZGC is powerful, it comes with a few limitations:

  • Available only in Java 11 and newer (with full support in Java 15+).
  • Uses compressed oops only up to 16TB heaps.
  • Slightly higher CPU usage due to concurrent work.
  • Might not be ideal for very small applications with limited memory.

When to Use ZGC

ZGC is best used in applications that:

  • Need low-latency performance (e.g., trading platforms, real-time systems).
  • Have large heap sizes (more than 8GB, up to several terabytes).
  • Run on Java 15 or newer.
  • Must avoid long GC pauses at all costs.

However, if your application has a small heap or is already using G1GC effectively, then switching to ZGC may not bring significant benefits.

GC Logs Example (ZGC)

Below is a sample log entry from ZGC:

[2025-07-23T10:15:05.123+0000][info][gc,start] GC(0) Pause Young (Normal) (Mark Start)
[2025-07-23T10:15:05.125+0000][info][gc] GC(0) Pause Mark Start 1.500ms
[2025-07-23T10:15:05.126+0000][info][gc] GC(0) Concurrent Mark 30.000ms
[2025-07-23T10:15:05.157+0000][info][gc] GC(0) Concurrent Relocate 40.000ms
[2025-07-23T10:15:05.198+0000][info][gc,end] GC(0) Pause Relocate Start 1.000ms

In this example:

  • Each phase is logged with start, duration, and type.
  • Concurrent phases like Mark and Relocate happen while the app runs.
  • Pause times are extremely short (1–2 ms).

Conclusion

ZGC is a next-generation garbage collector designed for modern Java applications. It stands out by offering ultra-low pause times, scalability to huge heaps, and simplified tuning. While it may not be suitable for all environments, it is ideal for applications where performance and responsiveness matter the most.

As a novice, understanding how ZGC works will help you prepare for future Java projects that require low latency and large heap memory. Even if your current application doesn’t need ZGC, knowing about it gives you more flexibility in choosing the right garbage collector for your needs.

If your project demands high scalability, low pause times, and runs on newer Java versions, then ZGC could be the perfect choice.


You may be interested: