写点什么

CMS 前世今生

用户头像
叫练
关注
发布于: 2021 年 04 月 01 日
CMS前世今生

CMS 一直是面试中的常考点,今天我们用通俗易懂的语言简单介绍下。


垃圾回收器为什么要分区分代?



image.png


如上图:JVM 虚拟机将堆内存区域分代了,先生代是朝生夕死的区域,老年代是老不死的区域,不同的年代对象有不同特性,因此需要不同的垃圾收集器去处理。如下图,黑竖线左边的区域都是分代垃圾收集器,G1 之后内存就不分代了。


image.png


单线程垃圾收集器:Serial + Serial Old


Serial(SY),Serial Old(SO)是单线程垃圾收集器组合,垃圾收集线程是单线程的,随着现代内存区域越来越大,SY+SO 组合已经越来越少了。垃圾收集的单线程需要 STW 时间无疑越长。这种组合比较合适较早 JDK 版本。如下图,用户线程表示应用程序处理过程,垃圾收集线程表示垃圾线程清理垃圾过程,此阶段应用程序是需要等待垃圾线程 STW 的。


image.png


多线程垃圾收集器:PS+PO


前面我们说了,单线程垃圾收集器缺点就是当内存区域变大,收集效率会很低,那 OK,摇身一变,如下图,多线程垃圾处理器。


image.png


值得注意的是:PS+PO 组合是 JDK1.7,JDK1.8 默认垃圾收集器。通过 java -XX:+PrintCommandLineFlags 命令可以在 Dos 界面查看。如下图,该命令可以查看 JVM 初始化的默认参数。比如:-XX:InitialHeapSize 表示初始化堆大小。


image.png


为啥蹦出来个 CMS+ParNew


并行处理有了,CMS+ParNew 又是干嘛的?其实 PO 关注是吞吐量,而 CMS 关注是缩短 STW 时间。而 CMS 处理流程更复杂,至于 ParNew,其实约等于 PS,如果你注意最上面一个图,你会发现 PS 年轻代无法和 CMS 组合。所以就多出来了一个 ParNew。


介绍 CMS 阶段


CMS,全名称 Concurrent Mark Sweep,中文释义并发标记清除,从名字上可以看出算法思想使用标记清除算法,下面我们看看 CMS 简化处理流程。


image.png


  • 初始标记。只标记 GC root 可达的第一个节点。会短暂的 STW。

  • 并发标记。用户线程和垃圾线程同时进行。垃圾线程会继续向下寻找 GCroot,不会有 STW。但也会有两个问题。

  • 多标:之前不是垃圾,现在线程出栈引用断开了变成了垃圾。也称为浮动垃圾。

  • 错标:之前已经被标注是垃圾,但现在重新引用。

  • 重新标记。STW 时间一般低于 200 毫秒。

  • 并发清除。并发清除时,因为用户线程和垃圾线程一起工作,如果 CMS 线程异常,可能会触发 SO 单线程执行。程序可能会特别缓慢。

劣势:碎片严重。


总结


主要简单介绍了分代垃圾回收器,特别介绍了 cms 执行过程,G1 留下次再说吧。好了,文章有地方还写的不清晰希望亲们加以指正和点评,喜欢的请点赞加关注哦。点关注,不迷路,我是叫练,边叫边练,公众号叫练,微信号【jiaolian123abc】。祝大家生活愉快。

发布于: 2021 年 04 月 01 日阅读数: 24
用户头像

叫练

关注

我是叫练,边叫边练 2020.06.11 加入

Java高级工程师,熟悉多线程,JVM

评论

发布
暂无评论
CMS前世今生