Backend Development 17 min read

Unlock Sub-Millisecond Pauses: Deep Dive into Java’s Z Garbage Collector (ZGC)

ZGC, introduced in JDK 11 and stabilized in JDK 15, is a low‑latency, region‑based, concurrent garbage collector that aims for sub‑millisecond pause times regardless of heap size, leveraging colored pointers, NUMA awareness, multi‑mapping, and read barriers to achieve efficient memory reclamation.

Ops Development Stories
Ops Development Stories
Ops Development Stories
Unlock Sub-Millisecond Pauses: Deep Dive into Java’s Z Garbage Collector (ZGC)

ZGC Overview

Z Garbage Collector (ZGC) is a scalable low‑latency garbage collector introduced in JDK 11 and stabilized in JDK 15. Its design goals are:

< 1ms maximum pause time (JDK < 16: 10 ms, JDK ≥ 16: < 1 ms)

Pause time does not increase with heap, live‑set, or root‑set size

Supports heap sizes from 8 MB up to 16 TB

ZGC has the following characteristics:

Concurrent

Region‑based layout

Compressed

NUMA‑aware

Uses colored pointers

Uses load barriers

Key Features

ZGC is a (temporarily) non‑generational collector built on a region‑based memory layout. It employs read barriers, colored pointers, and multi‑mapping to implement a concurrent mark‑compact algorithm with low latency as the primary goal.

Memory Layout

ZGC does not use generations.

Like Shenandoah and G1, ZGC uses a region‑based heap, but its regions are dynamic: they can be created and destroyed on demand, and their capacity can change. On x64 platforms, regions come in three sizes:

Small Region (2 MB) – stores objects smaller than 256 KB

Medium Region (32 MB) – stores objects between 256 KB and 4 MB

Large Region – size is a multiple of 2 MB and holds objects 4 MB or larger

NUMA‑Aware

NUMA (Non‑Uniform Memory Access) provides each CPU with a local memory region, reducing contention compared to UMA (Uniform Memory Access). ZGC automatically detects and exploits NUMA topology to improve performance on large‑scale servers.

Colored Pointer

Colored pointers store GC metadata directly in the object reference instead of the object header. Each 64‑bit pointer is divided as follows:

18 bits reserved for future use

1 bit – Finalizable flag

1 bit – Remapped flag

1 bit – Marked1 flag

1 bit – Marked0 flag

42 bits – Object address (supports up to 4 TB)

Why two mark bits? Each GC cycle swaps the active mark bit, invalidating the previous cycle’s marks so that all references start as unmarked.

Can ZGC compress pointers? No; ZGC uses 64‑bit pointers, allowing addressing up to 4 TB, far beyond the 32 GB limit of compressed 32‑bit pointers.

Advantages of Colored Pointers

When all live objects in a region are moved, the region can be released immediately because the forward table records old‑to‑new addresses.

Self‑healing pointers reduce the need for write barriers; only a read barrier is required.

18 unused bits provide ample space for future extensions.

Multi‑Mapping Addressing

ZGC uses multi‑mapping on Linux to map several virtual addresses to the same physical memory, allowing the colored pointer’s flag bits to act as address segment selectors. This technique is a by‑product of colored pointers rather than a dedicated feature.

Read Barrier

ZGC uses a read barrier to correct stale references during concurrent relocation. When a thread accesses an object that has been moved, the barrier checks the Remapped flag and redirects the reference to the new location.

<code>Object o = obj.fieldA;    // Loading an object reference from heap
<load barrier needed here>
Object p = o;            // No barrier, not a load from heap
o.doSomething();        // No barrier, not a load from heap
int i = obj.fieldB;      // No barrier, not an object reference</code>

The presence of load barriers adds roughly a 4 % overhead to application throughput.

ZGC Work Process

ZGC operates in four main concurrent phases:

Concurrent Mark : Traverses the object graph to determine reachability, updating the Marked0/Marked1 bits in colored pointers.

Concurrent Prepare for Relocate : Selects Regions to be relocated (the Relocation Set) based on heuristics.

Concurrent Relocate : Copies live objects to new Regions, builds a forward table, and uses read barriers to self‑heal stale references.

Concurrent Remap : Fixes remaining stale references; this work is merged into the next marking phase to avoid an extra traversal.

Core Parameters

-XX:+UseZGC – Enable ZGC

-Xmx – Set maximum heap size

-Xlog:gc – Enable GC logging

-Xlog:gc* – Enable detailed GC logging

GC Trigger Conditions

Timer‑based : Configurable via ZCollectionInterval

Warm‑up : Triggers at 10 %, 20 %, 30 % heap usage (up to three times)

Allocation Rate : Predicts when the heap will be exhausted based on recent allocation speed

Proactive : Triggers if heap growth exceeds 10 % within 5 minutes

Metadata Allocation : Triggers when metadata space is low

Explicit : System.gc() call

Allocation Stall : Threads block because the heap is full

ZGC Log Analysis Example

The following Java program runs with

-XX:+UseZGC -Xmx8m -Xlog:gc*

on JDK 17. The log shows phases such as Start, Phase‑Pause Mark Start/End, Phase‑Pause Relocate Start, heap size changes, and statistical summaries.

<code>/**
 * VM Args:-XX:+UseZGC -Xmx8m -Xlog:gc*
 */
public class HeapOOM {
    public static void main(String[] args) {
        List<byte[]> list = new ArrayList<>();
        while (true) {
            list.add(new byte[2048]);
        }
    }
}
</code>

Conclusion

The article described ZGC’s concepts, features, and workflow.

Most companies still use JDK 8/11 with ParNew+CMS or G1 collectors.

Java developers should stay curious about new technologies like ZGC to maintain a competitive edge.

References

Deep Understanding of the JVM, 3rd Edition – Zhou Zhimin

https://wiki.openjdk.java.net/display/zgc/Main

http://cr.openjdk.java.net/~pliden/slides/ZGC-Jfokus-2018.pdf

https://tech.meituan.com/2020/08/06/new-zgc-practice-in-meituan.html

JavaJVMGarbage CollectionZGCLow Latency
Ops Development Stories
Written by

Ops Development Stories

Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.