G1触发GC的场景

198 阅读3分钟

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%

  • 核心机制
    1. 并发标记周期启动:扫描全堆存活对象,计算各Region回收价值(垃圾占比/回收耗时)。
    2. 混合回收执行:回收所有年轻代Region + 高价值老年代Region(存活对象占比低于XX:G1MixedGCLiveThresholdPercent=85%的区域)。
  • 设计目标:在可控停顿(XX:MaxGCPauseMillis)内最大化垃圾回收量。

⚠️ 三、完全GC(Full GC)

Full GC是G1的退化场景,停顿达秒级,需极力避免。触发条件包括:

  1. 并发模式失败(Concurrent Mode Failure)
    • 原因:并发标记未完成时,老年代已满。
    • 解决方案:调低InitiatingHeapOccupancyPercent提前触发标记,或增大堆内存。
  2. 晋升失败(Promotion Failure)
    • 原因:Young GC时存活对象需晋升老年代,但老年代无连续空间(日志提示to-space exhausted)。
    • 解决方案:增大XX:G1ReservePercent(默认10%)预留空间,或减少对象晋升速度。
  3. 巨型对象分配失败(Humongous Allocation Failure)
    • 原因:分配超过Region 50%的大对象时,连续Humongous Region不足。
    • 解决方案:增大XX:G1HeapRegionSize(如32MB)或直接扩容堆内存。

⚙️ 四、其他触发场景

  1. 显式调用
    • System.gc()Runtime.getRuntime().gc()强制触发Full GC(可通过XX:+ExplicitGCInvokesConcurrent转为并发标记)。
  2. 元空间不足
    • 类元数据(Metaspace)耗尽时触发Full GC。
  3. 主动系统检查
    • JVM安全点(Safepoint)机制定期触发并发标记。

💎 总结与参数调优建议

GC类型触发条件关键参数优化目标
Young GCEden区满G1MaxNewSizePercent减少频率
Mixed GC老年代 > 45%InitiatingHeapOccupancyPercent提前标记、避免Full GC
Full GC并发失败/晋升失败/大对象失败G1ReservePercent, G1HeapRegionSize预留空间、避免退化

​调优优先级​​:

  1. 监控GC日志(Xlog:gc*)识别高频触发场景;
  2. 优先调整MaxGCPauseMillis(默认200ms)平衡吞吐与延迟;
  3. 避免显式设置年轻代大小(Xmn),保持G1动态调整能力。

通过合理配置,G1可在大堆(>6GB) 场景下实现亚秒级停顿,同时将Full GC风险降至最低。