跳到主要内容

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)并发标记期通过写屏障记录旧值,保持“开始快照”的一致性。

标记-复制-混合回收

典型周期:

  1. 年轻代 GC(复制 Eden→Survivor/Old,STW);
  2. 并发标记(从根出发标记存活对象,部分阶段并发);
  3. 混合回收(Mixed GC):选择收益高的 Old + 年轻代 Region 一起回收;
  4. 整体目标是以可控的暂停时间分批回收最“脏”的 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。