CMS垃圾收集器

CMS介绍

CMS全称Concurrent Mark Sweep,从名字可知是基于“标记——清除”算法实现。以获取最短回收停顿时间为目标;


CMS垃圾收集器.png

总的来说,由上图可知CMS垃圾回收有四个步骤:

  • 初始标记(Initial Mark)
    标记GC Roots能直接关联到的对象,速度很快。
  • 并发标记(concurrent mark)
    遍历初始标记阶段标记出来的存活对象,然后继续递归标记这些对象可达的对象
  • 重新标记(remark)
    修正由于并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录
  • 并发清理(concurrent sweep)
    与用户线程一起运行,清理那些无效的对象。

其中初始标记和重新标记需要Stop The World,但时间很短。并发标记与并发清理需要时间较长,但是可以和用户线程并发执行。

CMS缺点:

  • 无法处理浮动垃圾而导致concurrent mode failure

浮动垃圾:由于CMS并发清理阶段,用户线程的运行会导致新的垃圾产生,但是这一部分垃圾出现在标记阶段之后,CMS无法在当次收集中处理,只能在下次GC中清理,这一部分垃圾就称为“浮动垃圾”。

所以说CMS需要在老年代预留部分空间供并发收集时的程序运作使用。那么问题来了,CMS什么时候开始工作呢?也就是说CMS在老年代在使用百分之多少的空间时激活呢。太小不行,使用内存空间会小,这样垃圾容易满,GC次数会变多。

在JDK1.6中,阈值为92%(通过-XX:CMSInitiatingOccupancyFraction=)设置,预留的8%空间如果无法满足程序需要,就会出现concurrent mode failure。

这时JVM就会启用Serial Old收集器重新进行单线程STOP The World垃圾收集。效率极具下降。

  • 基于“标记——清除”算法会产生内存碎片,进而导致promotion failure

这是一个剩余空间不够的问题,剩余空间不够不是说整体的空间不够分配某个对象,而是说连续的空间不够分配给某个对象。所以一旦内存碎片大多就可能发生剩余空间不够的问题。(-XX:UseCMSCompactAtFullCollection和-XX:CMSFullGCBeforeCompaction=0 配合使用可以设置每次进行Full GC都开启碎片整理,不过这两个默认就是开启的,实际不需要设置)

promotion failure:minor gc过程中,另一个survivor的剩余空间不足以容纳eden及当前在用survivor区间存活对象,只能将容纳不下的对象移到年老代(promotion),而此时年老代由于剩余空间不够,无法容纳更多对象,通常伴随full gc,因而导致的promotion failure

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • CMS是老年代垃圾收集器,在收集过程中可以与用户线程并发操作。它可以与Serial收集器和Parallel New...
    zhong0316阅读 40,916评论 2 27
  • 本文转载一篇Blog,讲述了CMS promotion failed和concurrent mode failur...
    一帅阅读 1,865评论 0 2
  • Java和C++之间有一堵由内存动态分配和垃圾收集技术所围成的“高墙”,墙外面的人想进来,墙里面的人想出来。 对象...
    胡二囧阅读 1,147评论 0 4
  • JVM架构 当一个程序启动之前,它的class会被类装载器装入方法区(Permanent区),执行引擎读取方法区的...
    cocohaifang阅读 1,735评论 0 7
  • 气象中心昨天就发布了台风预报 室外作业的一支施工队今日停工,我们继续 今天的朋友圈关键词是疫苗 饭后坐院子里蹭凉,...
    禾伤阅读 297评论 0 0