G1触发GC的场景
G1垃圾收集器(Garbage-First)的垃圾回收(GC)触发场景主要分为以下四类,涵盖不同内存压力、对象分配行为和系统干预情况:
🔧 一、年轻代GC(Young GC)
触发条件:Eden区Region耗尽
- 机制:当线程通过TLAB或指针碰撞分配对象时,若Eden区所有Region均无可用空间,则触发Young GC。
- 处理过程:
- 存活对象从Eden复制到Survivor Region(年龄递增),年龄超阈值(默认15)则晋升老年代。
- 清空Eden和已回收的Survivor Region,更新RSet(Remembered Set)记录跨代引用。
- 优化建议:通过
XX:G1MaxNewSizePercent(默认60%)限制年轻代最大占比,避免频繁Young GC。
🔄 二、混合GC(Mixed GC)
触发条件:老年代占用率超过阈值(默认-XX:InitiatingHeapOccupancyPercent=45%)
- 核心机制:
- 并发标记周期启动:扫描全堆存活对象,计算各Region回收价值(垃圾占比/回收耗时)。
- 混合回收执行:回收所有年轻代Region + 高价值老年代Region(存活对象占比低于
XX:G1MixedGCLiveThresholdPercent=85%的区域)。
- 设计目标:在可控停顿(
XX:MaxGCPauseMillis)内最大化垃圾回收量。
⚠️ 三、完全GC(Full GC)
Full GC是G1的退化场景,停顿达秒级,需极力避免。触发条件包括:
- 并发模式失败(Concurrent Mode Failure)
- 原因:并发标记未完成时,老年代已满。
- 解决方案:调低
InitiatingHeapOccupancyPercent提前触发标记,或增大堆内存。
- 晋升失败(Promotion Failure)
- 原因:Young GC时存活对象需晋升老年代,但老年代无连续空间(日志提示
to-space exhausted)。 - 解决方案:增大
XX:G1ReservePercent(默认10%)预留空间,或减少对象晋升速度。
- 原因:Young GC时存活对象需晋升老年代,但老年代无连续空间(日志提示
- 巨型对象分配失败(Humongous Allocation Failure)
- 原因:分配超过Region 50%的大对象时,连续Humongous Region不足。
- 解决方案:增大
XX:G1HeapRegionSize(如32MB)或直接扩容堆内存。
⚙️ 四、其他触发场景
- 显式调用
System.gc()或Runtime.getRuntime().gc()强制触发Full GC(可通过XX:+ExplicitGCInvokesConcurrent转为并发标记)。
- 元空间不足
- 类元数据(Metaspace)耗尽时触发Full GC。
- 主动系统检查
- JVM安全点(Safepoint)机制定期触发并发标记。
💎 总结与参数调优建议
| GC类型 | 触发条件 | 关键参数 | 优化目标 |
|---|---|---|---|
| Young GC | Eden区满 | G1MaxNewSizePercent | 减少频率 |
| Mixed GC | 老年代 > 45% | InitiatingHeapOccupancyPercent | 提前标记、避免Full GC |
| Full GC | 并发失败/晋升失败/大对象失败 | G1ReservePercent, G1HeapRegionSize | 预留空间、避免退化 |
调优优先级:
- 监控GC日志(
Xlog:gc*)识别高频触发场景;- 优先调整
MaxGCPauseMillis(默认200ms)平衡吞吐与延迟;- 避免显式设置年轻代大小(
Xmn),保持G1动态调整能力。
通过合理配置,G1可在大堆(>6GB) 场景下实现亚秒级停顿,同时将Full GC风险降至最低。