这应该是全网最全的CMS学习笔记了-cms教程大全

引子带着问题去学习一个东西 。才会有目标感 。我先把一直以来自己对cms的有的疑惑罗列了下 。渴望这一篇学习笔记能解决掉这些疑惑 。渴望也能对你有所帮助 。
CMS出现的初心、背景和目的?CMS的适合用场景?CMS的trade-off是什么?优势、劣势和代价CMS会回收哪个地区的对象?CMS的GC Roots包括那些对象?CMS的过程?CMS和Full gc是不是一回事?CMS何时触发?CMS的日志怎么样解析?CMS的调优怎么样做?CMS扫描那些对象?CMS和CMS collector的区别?CMS的介绍参数设置?为什么ParNew可以和CMS搭配使用 。而Parallel Scanvenge不可以?一、基本知识CMS获得器:Mostly-Concurrent获得器 。也称并发标记清除获得器(Concurrent Mark-Sweep GC 。CMS获得器) 。它管理新生代的方法与Parallel获得器和Serial获得器相同 。而在老时代则是尽可能得并发执行 。每一个垃圾获得器周期只有2次短停顿 。我以前对CMS的理解 。以为它是针对老时代的获得器 。今天查阅了《java性能优化权威指南》和《Java性能权威指南》两本书 。确认以前的理解是错误的 。CMS的初心和目的:为了消除Throught获得器和Serial获得器在Full GC周期中的很长时间停顿 。CMS的适合用场景:如果你的应用需要更快的响应 。不渴望有很长时间的停顿 。同一时间你的cpu资源也比较多姿多彩 。就适适合用CMS获得器 。二、CMS的过程CMS的正常过程
这里我们首先就这样看下CMS并发获得周期正常完成的几个情况 。
(STW)初始标记:这种阶段是标记从GcRoots直接可达的老时代对象、新生代引用的老时代对象 。就是下图中灰色的点 。这种过程是单线程的(JDK7以前单线程 。JDK8之后并行 。可以通过参数CMSParallelInitialMarkEnabled修改) 。

这应该是全网最全的CMS学习笔记了-cms教程大全

文章插图
初始标记标记的对象
并发标记:由上一个阶段标记过的对象 。开始tracing过程 。标记任何可达的对象 。这种阶段垃圾回收线程和应用线程同一时间运行 。如上图中的灰色的点 。在并发标记过程中 。应用线程还在跑 。因此会导致有的对象会从新生代晋升到老时代、有的老时代的对象引用会被变化、有的对象会直接分配到老时代 。这些受到波及的老时代对象所在的card会被标记为dirty 。用来从头开始标记阶段扫描 。这种阶段过程中 。老时代对象的card被标记为dirty的可能原因 。就是下图中绿帽色的线:
这应该是全网最全的CMS学习笔记了-cms教程大全

文章插图
并发标记过程中受到波及的对象
预清理:预清理 。也是用来标记老时代存活的对象 。目的是为了让从头开始标记阶段的STW尽可能短 。这种阶段的目标是在并发标记阶段被应用线程波及到的老时代对象 。包括:(1)老时代中card为dirty的对象;(2)幸存区(from和to)中引用的老时代对象 。因此 。这种阶段也需要扫描新生代+老时代 。【ps:会不会扫描Eden区的对象 。我就这样看源代码猜测是没有 。还需要继续求证】
这应该是全网最全的CMS学习笔记了-cms教程大全

文章插图
预清理中扫描from和to区
可中断的预清理:这种阶段的目标跟“预清理”阶段相同 。也是为了减少从头开始标记阶段的事情量 。可中断预清理的价值:在进入从头开始标记阶段以前尽量等到一个Minor GC 。尽量缩短从头开始标记阶段的停顿时光 。另外可中断预清理会在Eden达到50%的时候开始 。这时候离下一次minor gc还有半程的时光 。这种还有另外一个意义 。即避免短暂的时间内连着的两个停顿 。如下图资料所示:
这应该是全网最全的CMS学习笔记了-cms教程大全

文章插图
避免连续停顿的发生
在预清理步骤后 。如果满足下面两个条件 。就不会开启可中断的预清理 。直接进入从头开始标记阶段:
Eden的使用空间大于“CMSScheduleRemarkEdenSizeThreshold” 。这种参数的默认值是2M;Eden的使用率大于等于“CMSScheduleRemarkEdenPenetration” 。这种参数的默认值是50% 。如果不满足上面两个条件 。则进入可中断的预清理 。可中断预清理可能会执行多次 。那么退出这种阶段的出口有两个(源码参见下图):
设置了CMSMaxAbortablePrecleanLoops 。并且执行的次数超过了这种值 。这种参数的默认值是0; CMSMaxAbortablePrecleanTime 。执行可中断预清理的时光超过了这种值 。这种参数的默认值是5000毫秒 。
这应该是全网最全的CMS学习笔记了-cms教程大全

文章插图
可中断预清理退出的条件
如果是因为这种原因退出 。gc日志打印如下:

推荐阅读