CMS 前世今生
CMS 一直是面试中的常考点,今天我们用通俗易懂的语言简单介绍下。
垃圾回收器为什么要分区分代?
如上图:JVM 虚拟机将堆内存区域分代了,先生代是朝生夕死的区域,老年代是老不死的区域,不同的年代对象有不同特性,因此需要不同的垃圾收集器去处理。如下图,黑竖线左边的区域都是分代垃圾收集器,G1 之后内存就不分代了。
单线程垃圾收集器:Serial + Serial Old
Serial(SY),Serial Old(SO)是单线程垃圾收集器组合,垃圾收集线程是单线程的,随着现代内存区域越来越大,SY+SO 组合已经越来越少了。垃圾收集的单线程需要 STW 时间无疑越长。这种组合比较合适较早 JDK 版本。如下图,用户线程表示应用程序处理过程,垃圾收集线程表示垃圾线程清理垃圾过程,此阶段应用程序是需要等待垃圾线程 STW 的。
多线程垃圾收集器:PS+PO
前面我们说了,单线程垃圾收集器缺点就是当内存区域变大,收集效率会很低,那 OK,摇身一变,如下图,多线程垃圾处理器。
值得注意的是:PS+PO 组合是 JDK1.7,JDK1.8 默认垃圾收集器。通过 java -XX:+PrintCommandLineFlags 命令可以在 Dos 界面查看。如下图,该命令可以查看 JVM 初始化的默认参数。比如:-XX:InitialHeapSize 表示初始化堆大小。
为啥蹦出来个 CMS+ParNew
并行处理有了,CMS+ParNew 又是干嘛的?其实 PO 关注是吞吐量,而 CMS 关注是缩短 STW 时间。而 CMS 处理流程更复杂,至于 ParNew,其实约等于 PS,如果你注意最上面一个图,你会发现 PS 年轻代无法和 CMS 组合。所以就多出来了一个 ParNew。
介绍 CMS 阶段
CMS,全名称 Concurrent Mark Sweep,中文释义并发标记清除,从名字上可以看出算法思想使用标记清除算法,下面我们看看 CMS 简化处理流程。
初始标记。只标记 GC root 可达的第一个节点。会短暂的 STW。
并发标记。用户线程和垃圾线程同时进行。垃圾线程会继续向下寻找 GCroot,不会有 STW。但也会有两个问题。
多标:之前不是垃圾,现在线程出栈引用断开了变成了垃圾。也称为浮动垃圾。
错标:之前已经被标注是垃圾,但现在重新引用。
重新标记。STW 时间一般低于 200 毫秒。
并发清除。并发清除时,因为用户线程和垃圾线程一起工作,如果 CMS 线程异常,可能会触发 SO 单线程执行。程序可能会特别缓慢。
劣势:碎片严重。
总结
主要简单介绍了分代垃圾回收器,特别介绍了 cms 执行过程,G1 留下次再说吧。好了,文章有地方还写的不清晰希望亲们加以指正和点评,喜欢的请点赞加关注哦。点关注,不迷路,我是叫练,边叫边练,公众号【叫练】,微信号【jiaolian123abc】。祝大家生活愉快。
版权声明: 本文为 InfoQ 作者【叫练】的原创文章。
原文链接:【http://xie.infoq.cn/article/a2e449edde6df6f51225331af】。文章转载请联系作者。
评论