JVM垃圾收集器之CMS

简介

CMS(Concurrent Mark Sweep)收集器是以获取最短回收停顿时间为目标,适合Java应用集中在互联网网站或者基于浏览器的B/S系统的服务端上。是基于标记-清除算法实现的。

运行过程

整个过程分为四个步骤:

  • 初始标记
  • 并发标记
  • 重新标记
  • 并发清除

其中初始标记、重新标记这两个步骤需要“Stop The World”。初始标记仅仅只是标记一下GC Roots能直接引用到的对象,速度很快;并发标记阶段就是GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长,不需要停顿用户线程,可以与垃圾收集线程一起并发运行,所以这个阶段会导致标记产生变动,但会被记录下来;重新标记阶段是为了修正并发标记期间记录的标记变动,最后是并发清除阶段,清理删除掉标记阶段的已经判断死亡的对象,不需要移动存活对象,所以可以与用户线程同时并发。下面是CMS收集器运行示意图:

在这里插入图片描述

浮动垃圾

在CMS的并发标记和并发清理阶段,用户线程还是在运行的,同时也会产生新的垃圾对象,但这一部分的垃圾对象是出现在标记过程结束以后的,CMS无法在当次收集中处理掉它们,只能在下一次垃圾收集时清理掉。这一部分垃圾就称为“浮动垃圾”。

缺点

虽然它有着并发收集、低停顿的优点,甚至被称为“并发低停顿收集器”。但至少还是有以下三个明显的缺点:

  • 吞吐量会收到影响。因为CMS是并发收集,在GC时,需要把执行用户的线程分出来一个执行GC,用户线程的执行速度会变慢,吞吐量会降低。由于面向并发设计的程序都会CPU有要求,所以如果CPU不是多核的或者核心数量比较少,也可能会对用户程序产生很大的影响。
  • CMS无法处理“浮动垃圾”,有可能出现“Con-current Mode Failure”失败进而导致另一次完全“Stop The World”的Full GC的产生。由于垃圾收集阶段,用户线程还在运行,浮动垃圾只能在下一次垃圾收集被清理,而一般收集器都是在老年代几乎被填满了再进行收集,如果在这时进行垃圾收集,可能会没有内存存储浮动垃圾,所以必须预留一部分空间供并发收集时使用。
  • 容易提前触发Full GC。因为CMS是基于“标记-清除”算法实现的收集器,会产生大量空间碎片,碎片过多时,虽然老年代还有很多剩余空间,但无法找到连续空间来话分配大对象,不得不提前触发一次Full GC。对于这个问题,在JDK9之前,CMS收集器在执行过若干次不整理空间的Full GC后,下一次进入Full GC前会先进行碎片整理。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值