Skip to content

G1 参数设置/Region/记忆集

G1 的关键参数

G1 有丰富的参数可以调优,但大多数情况下默认配置已经足够好。以下是需要重点关注的参数。

Region 相关参数

G1HeapRegionSize

设置 G1 Region 的大小:

bash
# 默认值:自动计算(1MB~32MB,必须是 2 的幂)
# 手动设置:
java -XX:G1HeapRegionSize=4m MyApp

# RegionSize 建议:
# - 堆小(< 4GB):Region 1MB
# - 堆中(4~32GB):Region 2MB 或 4MB
# - 堆大(> 32GB):Region 8MB 或 16MB

为什么要设置 RegionSize

堆大小默认 RegionSize说明
< 4GB1MB适合小堆
4~32GB2MB 或 4MB平衡
> 32GB8MB 或 16MB大堆需要大 Region

停顿时间参数

MaxGCPauseMillis

G1 最重要的参数:目标最大停顿时间

bash
# 设置目标停顿时间 200ms
java -XX:MaxGCPauseMillis=200 MyApp

# 设置目标停顿时间 100ms(更激进)
java -XX:MaxGCPauseMillis=100 MyApp

注意MaxGCPauseMillis 是一个软目标,不是硬性保证。JVM 会尽力满足,但不一定能保证。

bash
# MaxGCPauseMillis 的影响:
# 设置值越小 → G1 会收集更少的 Region → 停顿时间短
# 设置值越大 → G1 会收集更多的 Region → 停顿时间长但吞吐更高

G1HeapWastePercent

设置允许的 GC 浪费空间比例:

bash
# 默认值:5%
# 表示:如果空闲空间占堆的 5%,G1 可以停止收集
java -XX:G1HeapWastePercent=10 MyApp

年轻代参数

NewRatio 和 NewSize

bash
# 设置年轻代比例(老年代:年轻代 = NewRatio:1)
java -XX:NewRatio=2 MyApp
# 例如:堆 4GB,NewRatio=2 → 年轻代约 1.3GB,老年代约 2.7GB

# 或者直接设置年轻代大小
java -Xmn2g -XX:+UseG1GC MyApp

SurvivorRatio

bash
# 设置 Survivor 比例(Eden : Survivor)
# 默认值:8:1:1
java -XX:SurvivorRatio=4 MyApp
# Eden : Survivor = 4:1:1

InitialNewSize / MaxNewSize

bash
# 设置年轻代初始大小
java -XX:InitialNewSize=512m MyApp

# 设置年轻代最大大小
java -XX:MaxNewSize=2g MyApp

混合收集参数

InitiatingHeapOccupancyPercent

设置触发并发标记周期的堆使用率阈值:

bash
# 默认值:45(即老年代使用率达到 45% 时开始并发标记)
java -XX:InitiatingHeapOccupancyPercent=50 MyApp

G1MixedGCLiveThresholdPercent

混合收集时,Old Region 中存活对象比例超过这个阈值就不会被回收:

bash
# 默认值:85%
# 即:Old Region 中存活对象超过 85% 时,不值得回收
java -XX:G1MixedGCLiveThresholdPercent=90 MyApp

G1MixedGCCountTarget

一次混合收集周期中,最多执行多少次混合 GC:

bash
# 默认值:8
java -XX:G1MixedGCCountTarget=16 MyApp

G1 的 Remembered Set

什么是 Remembered Set

每个 G1 Region 都有一个 Remembered Set(RSet),记录「谁引用了我」:

┌────────────────────────────────────┐
│         Old Region                   │
│                                     │
│  RSet(记忆集):                    │
│  ├─ Eden Region A ──→ 引用了 Young Obj │
│  └─ Eden Region B ──→ 引用了 Young Obj │
│                                     │
└────────────────────────────────────┘

RSet 的作用

RSet 是 G1 实现可预测停顿的关键:

作用说明
避免全堆扫描GC 时不需要扫描整个堆,只需扫描 RSet
精确回收知道哪些 Region 有跨 Region 引用
并发优化RSet 的更新是并发的

RSet 的内存开销

RSet 需要额外的内存,每个 Region 的 RSet 大小取决于引用它的 Region 数量:

bash
# 默认情况下,RSet 占用约 5%~10% 的堆内存
# 可以通过参数调节:
java -XX:G1RSetUpdatingPauseTimePercent=5 MyApp

G1 调优实战

场景一:低延迟 Web 服务

bash
# 目标:停顿时间不超过 200ms
java -Xms4g -Xmx4g \
     -XX:+UseG1GC \
     -XX:MaxGCPauseMillis=200 \
     -XX:InitiatingHeapOccupancyPercent=45 \
     -XX:G1HeapRegionSize=4m \
     MyApp

场景二:高吞吐批处理

bash
# 目标:最大化吞吐量,允许较长停顿
java -Xms8g -Xmx8g \
     -XX:+UseG1GC \
     -XX:MaxGCPauseMillis=500 \
     -XX:G1HeapWastePercent=10 \
     -XX:G1MixedGCCountTarget=16 \
     MyApp

场景三:大内存机器

bash
# 64GB 堆,Region 大一些减少 RSet 开销
java -Xms64g -Xmx64g \
     -XX:+UseG1GC \
     -XX:MaxGCPauseMillis=200 \
     -XX:G1HeapRegionSize=8m \
     -XX:InitiatingHeapOccupancyPercent=50 \
     MyApp

常见问题与解决

问题原因解决
停顿时间过长收集 Region 太多减小 MaxGCPauseMillis
Full GC 频繁对象晋升太快增大 Survivor、降低晋升阈值
Humongous 对象多大对象太多增大 RegionSize 或调整阈值
GC 时间占比高吞吐量不够增大堆、减小 MaxGCPauseMillis

本节小结

G1 核心参数速查:

参数作用默认值
-XX:MaxGCPauseMillis目标最大停顿时间200ms
-XX:G1HeapRegionSizeRegion 大小自动(1~32MB)
-XX:InitiatingHeapOccupancyPercent触发并发标记的堆使用率45%
-XX:G1HeapWastePercent允许的浪费空间5%
-XX:G1MixedGCLiveThresholdPercentOld Region 回收阈值85%
-XX:NewRatio年轻代比例动态

理解 G1 的参数,是进行精细调优的基础。

下一节,我们来看 G1 回收过程/优化建议

基于 VitePress 构建