g1
G1 GC 机制与调优
ToC
- Region 与分代逻辑
- Remembered Set 与写屏障
- 标记-复制-混合回收
- 暂停预测与目标
- 常用参数与排查
Region 与分代逻辑
G1 将堆划分为若干等大小 Region(含 Eden/Survivor/Old/Humongous),按 Region 维度回收。分代仍然存在,但不再是物理连续的内存区。
Remembered Set 与写屏障(SATB)
- RSet 跟踪跨 Region 引用,回收某些 Region 时只扫描其相关 RSet;
- SATB(Snapshot-At-The-Beginning)并发标记期通过写屏障记录旧值,保持“开始快照”的一致性。
标记-复制-混合回收
典型周期:
- 年轻代 GC(复制 Eden→Survivor/Old,STW);
- 并发标记(从根出发标记存活对象,部分阶段并发);
- 混合回收(Mixed GC):选择收益高的 Old + 年轻代 Region 一起回收;
- 整体目标是以可控的暂停时间分批回收最“脏”的 Region。
暂停预测与目标
- 通过历史统计预测一次回收可处理的 Region 数量,努力满足
-XX:MaxGCPauseMillis=
; - 若目标过低导致回收跟不上分配,可能频繁 GC 或触发 Full GC。
常用参数与排查
-XX:+UseG1GC
(JDK9+ 默认);-XX:MaxGCPauseMillis=200
:目标暂停;-XX:InitiatingHeapOccupancyPercent=45
:并发标记触发阈值;-XX:G1ReservePercent
:预留避免晋升失败;-Xlog:gc*:tags,uptime,level
:打开详细 GC 日志,结合 GC Easy/JITWatch/JFR 分析;- 关注 Humongous 对象(> 1/2 Region 大小)可能导致碎片与回收效率下降。
Region 大小与 Humongous
-XX:G1HeapRegionSize=1m|2m|4m|8m|16m|32m
(启动时决定,取决于堆大小);- Humongous 对象(> 1/2 Region)直接分配在老年代连续 Region,频繁出现会影响回收;
- 缓解:提升 RegionSize、避免大对象(如大数组)或分块分配。
样例日志片段与解读
[2.345s][info][gc,start] GC(12) Pause Young (Normal) (G1 Evacuation Pause)
[2.345s][info][gc,phases] GC(12) Evacuate Collection Set: 3.2ms
[2.349s][info][gc,cpu] User=0.02s Sys=0.00s Real=0.00s
[5.678s][info][gc,start] GC(18) Pause Mixed (G1 Evacuation Pause)
[5.682s][info][gc,heap] GC(18) Eden regions: 8->0 Survivors: 2->3 Old: 104->96
- 关注 Young/Mixed 的暂停时长、回收量与晋升;
- Mixed 中 Old 减少表示回收有效;若 Old 长期不降、触发 Full GC,检查 IHOP 与标记周期。
调参思路(经验)
- 暂停过长:上调
MaxGCPauseMillis
或减小 Region 回收集(自动); - 回收不及时:降低
InitiatingHeapOccupancyPercent
提前标记; - 晋升失败:增加
G1ReservePercent
或堆大小; - Humongous 频繁:调整对象设计或 RegionSize。