Demystifying G1 GC: How Java’s Modern Collector Manages Heap Regions
This article walks through the G1 garbage collector’s heap structure, region‑based allocation, young‑generation collection steps, and the detailed phases of old‑generation collection, providing clear diagrams and practical insights for Java developers.
G1 Heap Structure
The G1 heap is divided into many fixed‑size blocks called regions. At JVM startup the region size is chosen (typically resulting in about 2,000 regions, each ranging from 1 MB to 32 MB).
Memory Allocation and Region Types
Each region is logically labeled as Eden, Survivor, or Old, similar to traditional collectors, but these labels are not physical partitions. G1 also defines a fourth type, Humongous, for objects larger than about 50 % of a region; such objects occupy a contiguous set of regions and are not fully optimized, so they should be avoided when possible.
Young Generation in G1
The heap’s ~2,000 regions are split between young and old generations. Young‑generation regions are typically colored green, old‑generation regions blue. Unlike older collectors, G1 does not require these regions to be contiguous, allowing flexible resizing.
A Young GC Cycle
During a young‑generation GC, surviving objects are copied to one or more Survivor regions; objects that have reached a tenure threshold are promoted to the old generation. This pause (a stop‑the‑world event) also measures the sizes of Eden and Survivor spaces for the next cycle, using the collected statistics to tune pause times.
After Young GC – Summary
The heap is a single memory space divided into many regions.
Young‑generation memory consists of a set of non‑contiguous regions, making capacity adjustments easy.
Young‑generation GC (young GCs) triggers a stop‑the‑world pause during which all application threads are paused.
Young‑generation GC runs in parallel across multiple threads.
Surviving objects are copied to new Survivor regions or promoted to the old generation.
Old‑Generation Collection in G1
Like the CMS collector, G1 aims for low‑pause old‑generation collection. The process consists of several phases, illustrated in the diagram below.
1. Initial Mark
The initial marking of live objects occurs during a young‑generation GC pause and is logged as GC pause (young)(initial-mark).
2. Concurrent Marking Phase
While the application runs, G1 computes region liveness in parallel. Empty regions (marked with a red “X”) are identified for immediate reclamation in the subsequent Remark phase.
3. Remark Phase
Empty regions are reclaimed, and the liveness of all regions is calculated (Region liveness).
4. Copying / Cleanup Phase
G1 selects regions with the lowest liveness for collection. These regions are reclaimed together with a concurrent young‑generation GC, resulting in a mixed pause logged as [GC pause (mixed)].
5. After Cleanup
The reclaimed regions are compacted into deep‑blue (old) and deep‑green (young) areas, as shown in the final diagram.
Old‑Generation GC Summary
Concurrent Marking Phase : Liveness is computed in parallel during program execution; no separate sweep phase unlike CMS.
Remark Phase : Uses the Snapshot‑at‑the‑Beginning (SATB) algorithm, which is faster than CMS; completely empty regions are reclaimed immediately.
Copying / Cleanup Phase : Young and old generations are collected together; whether an old‑generation region is selected depends on its liveness.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
