CMS收集器的主要设计目标是:低应用停顿时间。它经过两种方式实现这一目标:html
主要问题:因为不压缩带来的老年代堆碎片,或者在对象分配率高的状况下,均可能致使Full GC。java
CMS收集器的GC周期主要由7个阶段组成,其中有两个阶段会发生stop-the-world,其余阶段都是并发执行的。(亦有4个阶段、6个阶段等说法)数据结构
初始化标记阶段,是CMS GC的第一个阶段,也是标记阶段的开始。主要工做是标记可直达的存活对象。多线程
主要标记过程并发
程序执行状况oracle
(Marked obj:老年代绿色圆点表示被初始化标记的对象。)jvm
并发标记阶段,是CMS GC的第二个阶段。ide
在该阶段,GC线程和应用线程将并发执行。也就是说,在第一个阶段(Initial Mark)被暂停的应用线程将恢复运行。ui
并发标记阶段的主要工做是,经过遍历第一个阶段(Initial Mark)标记出来的存活对象,继续递归遍历老年代,并标记可直接或间接到达的全部老年代存活对象。线程
(Current obj:该对象的引用关系发生变化,对下一个对象的引用被删除。)
因为在并发标记阶段,应用线程和GC线程是并发执行的,所以可能产生新的对象或对象关系发生变化,例如:
对于这些对象,须要从新标记以防止被遗漏。为了提升从新标记的效率,本阶段会把这些发生变化的对象所在的Card标识为Dirty,这样后续就只须要扫描这些Dirty Card的对象,从而避免扫描整个老年代。
在并发预清洗阶段,将会从新扫描前一个阶段标记的Dirty对象,并标记被Dirty对象直接或间接引用的对象,而后清除Card标识。
标记被Dirty对象直接或间接引用的对象:
清除Dirty对象的Card标识:
本阶段尽量承担更多的并发预处理工做,从而减轻在Final Remark阶段的stop-the-world。
在该阶段,主要循环的作两件事:
具体执行多久,取决于许多因素,知足其中一个条件将会停止运行:
预清理阶段也是并发执行的,并不必定是全部存活对象都会被标记,由于在并发标记的过程当中对象及其引用关系还在不断变化中。
所以,须要有一个stop-the-world的阶段来完成最后的标记工做,这就是从新标记阶段(CMS标记阶段的最后一个阶段)。主要目的是从新扫描以前并发处理阶段的全部残留更新对象。
主要工做:
并发清理阶段,主要工做是清理全部未被标记的死亡对象,回收被占用的空间。
并发重置阶段,将清理并恢复在CMS GC过程当中的各类状态,从新初始化CMS相关数据结构,为下一个垃圾收集周期作好准备。
参考
psy-lob-saw.blogspot.com/2014/10/the…
更多文章,请关注公众号:二进制之路