Home G1 vs CMS 对比
Post
Cancel

G1 vs CMS 对比

G1 GC工作原理:

  1. 内存布局
    • 将堆划分为多个大小相等的Region(默认2048个,每个1-32MB)
    • Region类型:Eden、Survivor、Old、Humongous(大对象)
    • 大对象(超过Region 50%)直接分配到Humongous区域
  2. GC过程

    Young GC(Minor GC):

    1
    2
    3
    4
    5
    6
    7
    
    触发条件:Eden区满
    回收范围:所有Young Region
    过程:
    1. 扫描GC Roots + RSet(Remembered Set)
    2. 复制存活对象到Survivor或Old区
    3. 清空Eden和回收的Survivor区
    4. STW(Stop The World)时间可控
    

Mixed GC(混合GC):

1
2
3
4
5
6
7
   触发条件:老年代占堆比例达到阈值(默认45%)
   回收范围:所有Young Region + 部分Old Region
   过程:
   1. 初始标记(Initial Mark):STW,标记GC Roots
   2. 并发标记(Concurrent Mark):并发执行,标记存活对象
   3. 最终标记(Remark):STW,处理SATB(Snapshot-At-The-Beginning)
   4. 筛选回收(Cleanup):选择回收价值最大的Region

Full GC:

1
2
3
4
5
6
7
8
9
10
11
12
13
   触发条件:Mixed GC无法跟上分配速度、Metaspace不足
   特点:完全STW,性能差
   目标:尽量避免Full GC


-XX:+UseG1GC                      # 启用G1
   -XX:MaxGCPauseMillis=200          # 最大停顿时间目标(毫秒)
   -XX:G1HeapRegionSize=n            # Region大小(1-32MB)
   -XX:InitiatingHeapOccupancyPercent=45  # 触发Mixed GC的老年代占比
   -XX:G1NewSizePercent=5            # 年轻代最小占比
   -XX:G1MaxNewSizePercent=60        # 年轻代最大占比
   -XX:G1MixedGCCountTarget=8        # Mixed GC回收次数
   -XX:ConcGCThreads=n               # 并发GC线程数

G1 vs CMS 对比:

维度 G1 CMS
内存布局 Region化,灵活 固定分代
停顿时间 可预测,可控制 不可预测
内存碎片 复制算法,无碎片 标记-清除,有碎片
Full GC 较少 频繁(碎片导致)
CPU开销 中等(RSet维护)
适用场景 大堆(>6G),低延迟 中等堆,高吞吐
并发性 标记+回收并发 仅标记并发

选择G1的场景:

  1. 堆内存 ≥ 6GB
  2. 对响应时间敏感(如Web服务、在线交易)
  3. 需要可预测的停顿时间(如SLA要求P99 < 200ms)
  4. 避免Full GC导致的长时间停顿

选择CMS的场景:

  1. 堆内存 < 6GB
  2. 对吞吐量要求更高
  3. 已有稳定的CMS调优经验
  4. 注意:CMS在JDK9标记废弃,JDK14移除

实际案例: ``` 场景:电商订单服务,8G堆,QPS 5000 原配置:CMS,平均GC停顿300ms,P99停顿1s+

优化:

  1. 切换到G1:-XX:+UseG1GC -XX:MaxGCPauseMillis=200
  2. 结果:平均GC停顿150ms,P99停顿200ms
  3. 代价:CPU使用率提升5%(RSet维护)

结论:对于低延迟场景,G1是更好的选择

This post is licensed under CC BY 4.0 by the author.