首先CMS和G1都作为过java的主流垃圾收集器;
首先CMS是一款并发垃圾收集器,它的应用场景主要是一些互联网以及2B的业务场景(响应速度要快);
下面是引用的周志明java虚拟机那本书上的图,CMS大概分为四个步骤:初始标记、并发标记、重新标记、并发清理;
CMS的优点:
1:并发收集, 因为CMS收集器的第二步和第四步都是和用户线程一起工作,所以它的特点就是并发收集。
2:低停顿,停顿时间(stop the world)短,为什么CMS的停顿时间短,我们从它的四个步骤分析,CMS由一下四个步骤(初始标记、并发标记、重新标记、并发清理);第一个步骤是初始标记,这个步骤只是判断了对象的可达性,所以这一步用时其实是非常短的,第二步是并发标记,这个过程其实是gc的线程和我们的业务线程同时进行,所以这里没有stop the world,第三部是重新标记,这一步骤主要是处理并发标记期间新产生的垃圾,这步耗时比初始标记要长,但远比其它垃圾收集器的标记时间要短,最后一步是并发清除,也是没有stop the world,所以CMS垃圾收集器要比其它传统的垃圾收集耗时时间短。
CMS的缺点:
1:浮动垃圾,CMS垃圾收集器会产生浮动垃圾,因为我们的垃圾收集器第四步是并发清理,所以在并发清理这个过程中产生的对象垃圾,我们的收集器是清理不了的,这些垃圾只有等到下一次的fullGC才能被清理掉。
2:对cpu敏感,因为CMS垃圾收集器也是占用CPU线程资源的,所以在垃圾收集的过程中会导致用户程序变慢,影响程序的总吞吐量。CMS默认启用的回收线程数是(CPU+3)/4;
3:大对象进入老年代触发fullGC, 因为CMS的老年代收集算法是标记、清除算法,所以老年的内存碎片化比较严重,当我们有一个大对象要进入到老年代的时候,由于没有足够大的连续内存供存储该对象而不得不触发一次fullGC;当然有解决办法,CMS提供了一个参数:+UseCMSCompactAtFullCollection(默认开启),当老年代内存顶不住的进行fullGc的时候对内存进行碎片整理,但是这样垃圾收集的整个过程也会被拉长。另外CMS还提供了另外一个参数-XX CMSFullGCsBeforeCompaction,用于设定在执行多少次不压缩的fullGc后,紧接着来一次压缩的fullGc。
CMS先写到这,后面会再写一个G1的垃圾收集器博客。