G1 GC(Garbage-First):
JDK7u4 正式可用,JDK8 完善,作为可选低停顿 GC,替代 CMS 路线
详情:
bash
1. 设计核心思想
G1 = Garbage-First,面向低停顿、可预测 STW
打破传统新生代 / 老年代物理隔离,把整个堆划分为大小相等的 Region(默认 1M~32M):
1.1 Eden Region、Survivor Region、Old Region、Humongous Region(大对象区)
回收策略:优先回收垃圾最多的 Region,用最小 STW 换取最大内存释放。
2. G1 完整回收阶段(JDK8 版本)
2.1 年轻代回收(Young GC)
并行回收所有 Eden 区,存活对象复制到 Survivor,轻量 STW,停顿短;
2.2 并发标记周期(Concurrent Marking)
和应用线程并发执行,标记老年代存活对象,短暂 STW 仅出现在初始标记、重新标记;
2.3混合回收(Mixed GC)
并发标记完成后,挑选垃圾最多的若干 Old Region + 全部 Eden 一起回收,逐步清理老年代,避免一次性 Full GC;
2.4紧急 Full GC:内存耗尽、并发标记未完成时触发,单线程回收,停顿极长(JDK8 G1 最大痛点)
3. G1 对比 Parallel GC 的核心优势
3.1 可预测 GC 停顿
参数 -XX:MaxGCPauseMillis=200 硬约束单次 STW 上限,G1 会控制每次回收 Region 数量,在线业务延迟可控;
3.2.分块局部回收,不用整堆扫描,大堆(8G~32G)停顿远低于 Parallel GC;
3.3 逐步清理老年代,大幅降低 Full GC 触发频率;
3.4 原生支持 Humongous 大对象分区,减少大对象分配碎片;
3.5 并发标记和业务线程并行,CPU 空闲时间利用充分;
3.6 适合互联网微服务、接口服务、高并发 IO 业务。
4. G1 自身短板(对比后续 JDK17/21 ZGC、分代 ZGC、Shenandoah)
4.1 并发标记阶段存在开销
并发标记占用额外 CPU,纯 CPU 密集批处理场景,吞吐量不如 Parallel GC;
4.2 仍会发生长时间 STW Full GC
JDK8 G1 并发标记如果速度跟不上对象分配速度,堆内存快速占满,会触发单线程 Full GC,停顿比 Parallel GC 更差;
4.3 内存开销更高
需要维护每个 Region 的标记、存活统计、记忆集 Remembered Set,堆外内存占用高于 Parallel GC;
4.4 压缩机制局限
混合回收只清理部分老年代 Region,长期运行仍会产生老年代碎片,大对象分配依然可能触发 Full GC;
4.5 大堆极致低延迟能力不足
32G 以上超大堆,G1 混合回收停顿会逐步抬升,无法做到亚毫秒级停顿;
4.6 没有分代并发优化
JDK8 G1 不分代并发标记,老年代越多,并发标记周期越长;JDK21 分代 ZGC 彻底解决该问题。
5. G1 调优关键经验
5.1 MaxGCPauseMillis 不要设小于 50ms,会频繁 GC 吞吐暴跌
5.2 InitiatingHeapOccupancyPercent 默认 45,堆 > 8G 可调至 35 提前并发标记
5.3 出现 FullGC:排查内存泄漏、大对象、元空间溢出、堆外内存溢出