Fundamentals 30 min read

Mastering Java G1 and ZGC: Deep Dive into Modern Garbage Collectors

This article provides a comprehensive overview of Java's G1 and ZGC garbage collectors, explaining their memory layout, internal structures such as regions, card tables, and RSet, detailing Young and Mixed GC processes, three‑color marking, SATB, incremental updates, and the low‑pause design of ZGC.

Alibaba Cloud Developer
Alibaba Cloud Developer
Alibaba Cloud Developer
Mastering Java G1 and ZGC: Deep Dive into Modern Garbage Collectors

G1 (Garbage First) Garbage Collector

G1 was introduced in JDK7 and fully implemented in JDK8, becoming the default server‑side collector, replacing Parallel Scavenge. Compared with CMS, G1 offers predictable pause times and high throughput, allowing GC pauses to be limited to a configurable number of milliseconds.

G1 collects both young and old generations using a region‑based heap layout. The heap is divided into many variable‑size regions (1‑32 MiB, powers of two). Each region can act as Eden, Survivor, or old, but at any moment it has a single role. Regions are logically contiguous, not physically.

In addition to the traditional generations, G1 defines a special Humongous region for large objects whose size exceeds half a region; such objects are allocated directly into Humongous regions to avoid costly copying.

Region layout
Region layout

Region Internal Structure

Card Table : Each region is subdivided into cards; the collection of cards forms a card table used to track references.

Card table example
Card table example

RSet (Remembered Set) : A hash‑like structure that records cross‑generation references. The key is the address of a region that holds a reference, and the value is the set of cards in the current region that contain those references.

RSet enables G1 to avoid scanning the entire old generation when collecting the young generation. During Young GC, after scanning GC roots, G1 consults RSet to quickly identify old‑to‑young references and mark the corresponding young objects as live.

RSet example
RSet example

Young GC Process

Stop‑the‑World (STW) – the entire Young GC runs within an STW pause.

Scan GC Roots – identify objects directly reachable from roots; objects referenced from old generation are discovered via RSet.

Empty Dirty Card Queue – update RSet based on cards whose references have changed.

Scan RSet – determine which young objects are still reachable.

Copy live objects to Survivor or promote to old generation.

Process reference queues (soft, weak, phantom).

The above steps constitute the complete Young GC workflow.

Three‑Color Marking Algorithm

Objects are colored white (unvisited), gray (visited but fields not yet processed), or black (visited and fields processed). Starting from GC roots, reachable objects are eventually colored black; remaining white objects are reclaimed.

Two common marking gaps can cause missed objects:

Existing objects become unreachable due to reference changes during marking.

Newly allocated objects are created after their allocating thread has already been colored black.

Solutions include Snapshot‑At‑The‑Beginning (SATB) and Incremental Update, both relying on write barriers to record reference changes.

Mixed GC

Mixed GC combines a global concurrent marking phase with evacuation of live objects. The steps are:

Initial Mark (STW) – marks objects directly reachable from GC roots.

Root Region Scan – scans survivor regions to mark old objects referenced from them.

Concurrent Marking – performs reachability analysis while the application runs, using SATB to capture changes.

Remark (STW) – finalizes marking of objects that changed during the concurrent phase.

Cleanup – evaluates the reclamation value of each region and builds the Collection Set (CSet).

Evacuation – copies live objects to empty regions in a multithreaded STW phase.

G1’s region‑based approach reduces fragmentation and often yields better throughput and shorter pauses than CMS on large heaps.

ZGC (Z Garbage Collector)

ZGC, available experimentally since JDK11 and production‑ready from JDK17, aims for sub‑10 ms pause times by performing almost all work concurrently.

Page Memory Layout

ZGC divides the heap into pages rather than generations. Three page sizes exist:

Small page: 2 MiB, holds objects < 256 KiB.

Medium page: 32 MiB, holds objects 256 KiB – 4 MiB.

Large page: multiples of 2 MiB, each holds a single object > 4 MiB.

ZGC page layout
ZGC page layout

Key Techniques

Colored Pointers : The upper bits of a 64‑bit object reference encode GC state (marked0, marked1, remapped, finalizable). This enables the collector to identify an object’s phase without extra metadata.

Read Barriers : Inserted into every object load; when a thread reads a reference to an object that has been relocated, the barrier redirects the access using a forwarding table, achieving “pointer self‑healing”.

NUMA Awareness : ZGC detects non‑uniform memory access architectures and distributes pages across NUMA nodes to reduce contention.

ZGC Process

Initial Mark – marks all objects reachable from GC roots and switches the good_mask to the first marking state.

Concurrent Mark – continues reachability analysis while the application runs, updating per‑page live‑object statistics.

Remark – a brief STW phase that finalizes markings for objects whose references changed during concurrent marking.

Concurrent Prepare for Relocate – scans pages, builds forwarding tables, and assembles the Relocation Set.

Relocate Start (STW) – switches good_mask, copies directly reachable objects to new pages, and updates roots.

Concurrent Relocate – copies live objects according to forwarding tables; pages become reclaimable.

Concurrent Remap – defers full pointer remapping to the next GC cycle; read barriers handle on‑the‑fly remapping.

Because most phases run concurrently, ZGC achieves very low pause times at the cost of slightly lower throughput compared with G1.

ZGC Review

ZGC’s design excels in latency‑sensitive workloads, offering near‑zero stop‑the‑world pauses. Its trade‑off is reduced throughput, especially on pre‑JDK21 versions without generational support. As ZGC matures and gains generational capabilities, its performance gap with G1 is expected to narrow.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JVMMemory ManagementGarbage CollectionzgcG1
Alibaba Cloud Developer
Written by

Alibaba Cloud Developer

Alibaba's official tech channel, featuring all of its technology innovations.

0 followers
Reader feedback

How this landed with the community

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.