cms和g1回收器对比

0 对象存活的判断

        判断对象是否存活一般有两种方式:

  • 引用计数:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。此方法简单,缺点是无法解决对象相互循环引用的问题。
  • 可达性分析(Reachability Analysis):从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。

        在Java语言中,GC Roots包括:

  •   虚拟机栈中引用的对象。
  •   方法区中类静态属性实体引用的对象。
  •   方法区中常量引用的对象。
  •   本地方法栈中JNI引用的对象。

        由于循环引用的问题,一般采用跟踪(可达性分析)方法

1 GC算法

        GC常见指标:吞吐量、垃圾回收器、停顿时间、垃圾回收频率、反应时间

  • 吞吐量

应用系统的生命周期内,应用程序所花费的时间和系统总运行时间的比值。
系统总运行时间=应用程序耗时+GC耗时。
如果系统运行了100分钟,GC耗时1分钟,则系统吞吐量=99%

  • 垃圾回收器负载

垃圾回收器负载=GC耗时/系统总运行时间

  • 停顿时间

垃圾回收器运行时,应用程序的暂停时间

  • 垃圾回收频率

垃圾回收器多长时间运行一次。一般而言,频率越低越好,通常增大堆空间可以有效降低垃圾回收发生的频率,但是会增加回收时产生的停顿时间。

  • 反应时间

当一个对象成为垃圾后,多长时间内,它所占用的内存空间会被释放掉。

1.1 引用计算法

  • 优点
    • 可即时回收垃圾
    • 最大暂停时间短
    • 没有必要沿着指针查找
  • 缺点
    • 计数器值的增减处理非常繁重
    • 计算器需要占用很多位
    • 循环引用无法回收

1.2 标记-清除

  • 优点
    • 实现简单
    • 与保守式GC算法兼容
  • 缺点
    • 碎片化
    • 分配速度慢
    • 与写时复制技术不兼容

1.3 复制

        复制收集算法在对象存活率较高时就要进行较多的复制操作,效率将会变低。更关键的是,如果不想浪费50%的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都100%存活的极端情况,所以在老年代一般不能直接选用这种算法

  • 优点
    • 高吞吐量
    • 不会碎片化
    • 可高速分配
    • 与缓存兼容
  • 缺点
    • 复制收集算法在对象存活率较高时就要进行较多的复制操作,效率将会变低
    • 需要浪费50%的内存空间

1.4 标记-整理

        标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存

  • 优点
    • 弥补了标记-清除算法,内存区域分散的缺点
    • 弥补了复制算法内存减半的代价
  • 缺点
    • 效率不高,对于标记-清除而言多了整理工作,对于复制算法而言多了标记工作

1.5 功能对比

  • 效率:复制算法>标记整理>标记清除
  • 内存整齐度:复制=标记整理>标记清除
  • 内存使用率:标记整理=标记清除>复制

2 CMS回收器

        CMS回收过程:初始标记=》并发标记=》重新标记=》并发清除

  • 初始标记(CMS Initial Mark)—— 标记GC root能直接关联的对象(短暂STW)
  • 并发标记(CMS Concurrent Mark)—— GCRootsTracing,从并发标记中的root遍历,对不可达的对象进行标记
  • 重新标记(CMS Remark)—— 修正并发标记期间因为用户操作导致标记发生变更的对象,有STW
  • 并发清除(CMS Concurrent Sweep)

3. G1回收器

        G1回收过程:初始标记=》并发标记=》最终标记=》筛选回收

  • 初始标记(Initial Mark)—— 标记GC root能直接关联的对象(短暂STW)
  • 并发标记(Concurrent mark)—— GCRootsTracing,从并发标记中的root遍历,对不可达的对象进行标记,耗时长但可并行
  • 最终标记(Final Remark)—— 收集并发标记期间产生的新垃圾(短暂STW),采用了SATB算法比CMS更快
  • 筛选回收(Live Data Counting and Evacuation)—— 对各个Region的回收性价比排序,在保证时间可控的情况下清除失活对象,清除Remember Sets

4 CMS和G1对比

分代并发度清除算法、产生碎片是否可预测停顿
CMS

老年代

(需要其他收集器配合)

CMS对CPU资源敏感,需要占用25%的线程,如果核数小于4更会占用一半的资源标记-清除,会产生碎片
G1

老年代、年轻代

(不需要其他收集器配合)

并发度更高,充分利用CPU多线程整体上是标记-整理,局部是复制,不产生碎片

4.1 为什么CMS会产生浮动垃圾,而G1不会产 生浮动垃圾?

        由于CMS并发清理阶段用户线程还在运行着,伴随程序运行自然会有新垃圾产生,这部分垃圾得标记过程之后,所以CMS无法在当收集中处理掉他们,只好留待下一次GC清理掉,这一部分垃圾称为浮动垃圾。

        g1也同样会遇到浮动垃圾的问题,但相比于cms,g1采用了stab算法来解决浮动垃圾。stap全称snapshot-at-the-beginning,由Taiichi Yuasa为增量式标记清除垃圾收集器开发的一个算法,主要有以下几个特点:

  • stab算法主要应用于垃圾收集的并发标记阶段
  • stab算法保证了在并发标记过程中新分配对象不会漏标
  • 解决了CMS垃圾收集器重新标记阶段长时间STW的潜在风险

4.2 为什么CMS会产生内存碎片,而G1不会产生内存碎片?

  • CMS用的是标记清除算法,会产生内存碎片。
  • G1整体上是标记-整理,局部是复制,不产生碎片。

4.3 为什么CMS是并发的而不是并行的?

        为了解决因标记清除算法而会产生内存碎片的问题,CMS提供了-XX:UseCMSCompactAtFullCollection开发参数用于开启内存碎片的合并整理,由于内存整理是无法并行的,所以停顿时间会变长。还有-XX:CMSFullGCBeforeCompaction,这个参数用于设置多少次不压缩Full GC后,跟着来一次带压缩的(默认为0)。

4.4  为什么说CMS是对CPU资源敏感的?

        CMS默认启动的回收线程数是(cpu数量+3)/ 4,所以CPU数量少会导致用户程序执行速度降低较多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值