CMS 和G1 的区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CMS 和G1 的区别相关的知识,希望对你有一定的参考价值。

参考技术A

CMS收集器是老年代的收集器,可以配合新生代的Serial和ParNew收集器一起使用
G1收集器收集范围是老年代和新生代。不需要结合其他收集器使用

CMS收集器以最小的停顿时间为目标的收集器。

G1收集器可预测垃圾回收的停顿时间(建立可预测的停顿时间模型)

CMS收集器是使用“标记-清除”算法进行的垃圾回收,容易产生内存碎片

G1收集器使用的是“标记-整理”算法,进行了空间整合,降低了内存空间碎片。

初始标记
并发标记
重新标记
并发清理

初始标记阶段:会让线程全部停止,也就是 Stop the World 状态
并发标记阶段:对所有的对象进行追踪,这个阶段最耗费时。但这个阶段是和系统并发运行的,所以不会对系统运行造成影响
重新标记阶段:由于第二阶段是并发执行的,一边标记垃圾对象,一边创建新对象,老对象会变成垃圾对象。 所以第三阶段也会进入 Stop the World 状态,并且重新标记,标记的是第二阶段中变动过的少数对象,所以运行速度很快
并发清理阶段: 这个阶段也是会耗费很多时间,但由于是并发运行的,所以对系统不会造成很大的影响

CMS采用 标记-清理 的算法,标记出垃圾对象,清除垃圾对象。算法是基于老年代执行的,因为新生代产生无法接受该算法产生的碎片垃圾。

优点 :并发收集,低停顿

不足

G1的出现就是为了替换jdk1.5种出现的CMS,这一点已经在jdk9的时候实现了,jdk9默认使用了G1回收器,移除了所有CMS相关的内容。G1和CMS相比,有几个特点:

G1把Java内存拆分成多等份,多个域(Region),逻辑上存在新生代和老年代的概念,但是没有严格区分

贴图感受一下:

依旧存在新生代老年代的概念,但是没有严格区分。Region最多分为2048个

除了上面优点之外,还有一个优点,那就是对大对象的处理。在CMS内存中,如果一个对象过大,进入S1、S2区域的时候大于改分配的区域,对象会直接进入老年代。G1处理大对象时会判断对象是否大于一个Region大小的50%,如果大于50%就会横跨多个Region进行存放

初始标记: 标记GC Roots 可以直接关联的对象,该阶段需要线程停顿但是耗时短

并发标记: 寻找存活的对象,可以与其他程序并发执行,耗时较长

最终标记: 并发标记期间用户程序会导致标记记录产生变动(好比一个阿姨一边清理垃圾,另一个人一边扔垃圾)虚拟机会将这段时间的变化记录在Remembered Set Logs 中。最终标记阶段会向Remembered Set合并并发标记阶段的变化。这个阶段需要线程停顿,也可以并发执行

筛选回收: 对每个Region的回收成本进行排序,按照用户自定义的回收时间来制定回收计划

参考官方文档:

控制G1回收垃圾的时间

-XX:MaxGCPauseMillis=200 (默认200ms)

以上是关于CMS 和G1 的区别的主要内容,如果未能解决你的问题,请参考以下文章

JVM: G1和CMS的区别

JVM: G1和CMS的区别

JVM: G1和CMS的区别

CMS收集器和G1收集器的区别

CMS收集器和G1收集器的区别

CMS和G1的区别