Unlocking G1 GC: Why Your Java Service Hangs and How to Fix It
This article explains the G1 garbage collector’s heap layout, collection cycles, pause prediction, log analysis, and monitoring tools, helping Java developers diagnose and resolve performance issues such as frequent restarts, OOM, CPU spikes, and periodic latency spikes.
What does this article cover?
Heap layout (Region‑based: Eden, Survivor, Old, Humongous)
Garbage‑collection cycles
GC phases: initial mark, concurrent mark, final mark, evacuation
GC types: Minor, Full, Mixed
CSet (the set of Regions to collect in the young generation)
Cross‑generation references
Pause‑prediction model
GC log analysis
G1 Memory Heap Layout
G1 (Garbage‑First) is a generational collector that partitions the heap into Regions. The image below marks Humongous Regions (H) that store objects larger than half a Region.
Humongous objects are allocated directly in the old generation to avoid repeated copying.
They are reclaimed during the global concurrent marking cleanup and Full GC phases.
Before allocating a humongous object, G1 checks the Initiating Heap Occupancy Percent (IHOP) and the marking threshold; if exceeded, global concurrent marking starts to pre‑emptively reclaim space and avoid evacuation failures and Full GC.
GC Types
Young GC – collects young regions and humongous regions.
Mixed GC – collects young regions, old regions, and humongous regions.
Full GC – collects young, old, humongous regions, and Metaspace.
Collection Set (CSet)
The Collection Set is the group of Regions selected for collection in a given GC phase.
Young GC CSet: young regions + humongous regions.
Mixed GC CSet: young regions + old regions + humongous regions.
Cross‑Generation References
During Young GC, reachable objects are identified via GC roots. To avoid scanning the entire old generation for references to young objects, G1 records old‑to‑young references in a remembered set (RSet) implemented with a CardTable.
RSet (Remembered Set)
The RSet stores references from other Regions to a given Region, allowing the collector to locate live objects without scanning the whole heap. Each young Region maintains its own RSet, which can consume up to 20% of heap space.
CardTable
The old generation is divided into cards; each card records whether it contains references to the young generation. A value of 1 indicates a reference, which is then added to the RSet, improving the efficiency of cross‑generation reference queries.
Pause Prediction Model
G1 predicts pause times using variance‑based statistical models derived from historical data. (Reference: https://sdww2348115.github.io/jvm/g1/PausePredictionModel)
G1 GC Cycle
G1 alternates between two phases: Young‑only and Space Reclamation.
Young‑only: a series of operations that gradually promote long‑living objects to the old generation.
Space Reclamation: progressively reclaims space in the old generation while also handling young Regions.
When the old‑generation occupancy exceeds the InitiatingHeapOccupancyPercent (default 45%), G1 starts concurrent marking, which may take a long time but does not stop the application.
Blue circles: Young‑only pauses.
Yellow circles: Marking pauses.
Red circles: Mixed GC pauses.
GC Log Analysis
The following excerpt shows a series of G1 GC logs; each entry can be mapped to the phases described above.
[gc,start ] GC(44265) Pause Young (Normal) (G1 Evacuation Pause)
[gc,task ] GC(44265) Using 13 workers of 13 for evacuation
[gc,phases ] GC(44265) Pre Evacuate Collection Set: 0.1ms
[gc,phases ] GC(44265) Evacuate Collection Set: 101.8ms
[gc,phases ] GC(44265) Post Evacuate Collection Set: 3.2ms
[gc,phases ] GC(44265) Other: 2.7ms
[gc,heap ] GC(44265) Eden regions: 1850->0(1851)
[gc,heap ] GC(44265) Survivor regions: 70->69(240)
[gc,heap ] GC(44265) Old regions: 766->768
[gc,heap ] GC(44265) Humongous regions: 20->19
[gc,metaspace ] GC(44265) Metaspace: 193280K->193280K(1230848K)
[gc ] GC(44265) Pause Young (Normal) (G1 Evacuation Pause) 21642M->6843M(25600M) 107.561ms
[gc,cpu ] GC(44265) User=1.31s Sys=0.00s Real=0.11s
... (additional log entries omitted for brevity) ...Key observations:
GC(44265) is a normal Young GC showing region changes.
GC(44269) marks the start of the concurrent phase.
GC(44270) completes Cleanup, followed by Prepare Mixed GC (44271).
GC(44272) begins the Space Reclamation stage with multiple Mixed GCs.
Humongous objects are treated specially: G1 only decides their liveness and reclaims their space; they are never moved. During Young‑Only, humongous regions may be reclaimed. During Space Reclamation, humongous regions may be reclaimed.
JVM Performance Monitoring Tools
Useful tools for diagnosing JVM performance bottlenecks:
VisualVM
Glowroot
Arthas (https://arthas.aliyun.com/)
Thread‑dump analysis:
FastThread (https://fastthread.io/)
GC‑log analysis:
GCEasy (https://gceasy.io/gc-index.jsp)
Heap‑dump analysis:
IBM Heap Analyzer (https://www.ibm.com/support/pages/ibm-heapanalyzer)
Eclipse MAT (https://projects.eclipse.org/projects/tools.mat)
References
GC pause prediction model: http://www.narihiro.info/g1gc-impl-book/scheduling.html
GC pause prediction model: https://sdww2348115.github.io/jvm/g1/PausePredictionModel
Garbage collector execution process: https://bugs.openjdk.org/browse/JDK-8295118
Cross‑generation references: https://blog.csdn.net/weixin_47184173/article/details/113627337
Automatic heap memory return to OS: https://openjdk.org/jeps/346
Additional resources: https://docs.oracle.com/javacomponents/jmc-5-4/jfr-runtime-guide/comline.htm#JFRUH197, https://www.redhat.com/en/blog/part-1-introduction-g1-garbage-collector, https://blog.csdn.net/qq_16500963/article/details/132133125, http://cs.williams.edu/~dbarowy/cs334s18/assets/p37-detlefs.pdf, https://tech.meituan.com/2016/09/23/g1.html, https://hllvm-group.iteye.com/group/topic/44381
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.
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.
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.
