您的位置 首页 java

一文就懂Java虚拟机的CMS收集器原理及使用

一文弄明白Java HotSpot 虚拟机 的CMS收集器:原理及使用场景

作者 :吴潇

职位 :Java软件工程师

原创声明

这是本人的署名原创文章,未经许可不支持转载,请勿抄袭。本公众号的所有文章均为本人原创。为了更容易理解和记忆,今后所有文章将以图解为主、代码为辅,忽略不太重要的细节,但是保留关键性的技术细节。如果您感兴趣,欢迎关注!
 

今天打算分析一下Concurrent Mark Sweep (CMS) 垃圾收集器。

1. CMS收集器概述

CMS收集器的设计目标是 优先降低GC停顿时间 相对地降低吞吐量 ),并且适合于有足够CPU资源提供给GC 线程 使用的那些应用程序。所以,如果你需要较短的GC停顿时间并且CPU数量充足,那么建议使用CMS收集器。例如,如果应用程序有较多长期存活的对象,那么老年代就会很大,导致GC暂停时间很长,并且有至少2个以上cpu核,那么适合使用CMS收集器。

2. 启用CMS收集器的方法

-XX:+UseConcMarkSweepGC
 

CMS收集器针对新生代和老年代分别独立回收(新生代minor gc,老年代major gc)。因为新生代空间较小,老年代空间较大,所以GC暂停时间大部分是老年代的major gc导致的。因此,CMS用多个垃圾回收线程来track老年代中的存活对象,并且这些线程与用户线程一起并发执行,这样可以减少major gc的停顿时间。

3. CMS的垃圾收集过程

CMS收集器的major gc过程是基于”Mark-Sweep回收 算法 “实现的,也就是说它分为Mark和Sweep两大阶段。因为Mark阶段最消耗时间,所以为了减少停顿,Mark阶段又被细分为Initial Mark,Concurrent Mark和Remark这3个标记阶段。因此,CMS的major gc过程总共分为4个阶段,如下图所示:

其中,

initial mark阶段 需要停顿(Stop The World) ,但是持续时间很短,只枚举出从GC Roots和新生代的中的对象可以直接引用到的对象。

concurrent mark阶段 :与用户线程并发运行,持续时间长但是不会停顿,需要占用一些用户线程的CPU资源,这个阶段会把老年代中所有存活和不存活对象枚举出来。

remark阶段 :因为concurrent mark阶段时间长并且是与用户线程并发运行,在这过程中,某些对象又会变成可回收,所以需要进行一些修正。remark阶段就是做这些修正的,并且修正过程 需要停顿 。这里的停顿时间比initial mark长一些。

sweep阶段 :将前面标记对象的内存回收,这个阶段GC线程与用户线程并发运行。

4. Concurrent mode failure

以上是正常情况下的Major GC回收过程,关键的地方都图中有所体现。通过让执行时间最长的concurrent mark阶段与用户线程并发运行,减少了停顿时间。特殊情况:如果CMS回收过程还没有执行完,老年代的剩余空间就用完了,或者,当前老年代空间不能满足一次内存分配请求(可能对象较大),那么此时将停顿所有用户线程,执行Full GC直到回收过程结束(不再区分concurrent mark和remark),然后再恢复用户线程,如下图所示。

5. 哪些情况会触发Full GC

之前遇到面试官问我哪些情况会触发Full GC,当时羞涩的我只回答出来老年代空间不够及System.gc这两种情况。其实,触发Full GC的原因有以下几点:

  1. 老年代的空闲空间快要不够(上图所示就是这种情况),例如已用空间达到92%以上。
  2. 老年代的空间不能满足一次分配请求(碎片太多,要分配的对象太大)。
  3. 显式 调用System.gc()。
  4. 调试工具请求获取 JVM 堆内存相关信息。

希望以上总结出的几个要点对于各位今后面试有用(可能不全,欢迎补充)。

6. 其他

CMS收集器在发现 老年代即将变满 的时候就开始一轮回收操作,例如已用空间的百分比达到92%。这是默认值,可以通过-XX:CMSInitiatingOccupancyFraction=<N>修改。

我们没有讲CMS收集器的minor gc。因为minor gc非常简单,就是执行”Copy算法”而已,把eden空间中的对象往survivor空间拷贝。

minor gc也停顿,时间也很短,可以与remark阶段的暂停时间比较;minor gc可以在major gc的执行过程中发生,与major gc的停顿阶段交替运行,但是不会重叠,如图:

最后再补充说明一下,这本《 深入理解Java虚拟机 :JVM高级特性与最佳时间》,虽然写的还行,但是跟JDK官方文档相比起来逊色太多而且有一些错误。如果 想把Java的垃圾回收相关知识理解好,少走弯路,建议看Java Platform, Standard Edition HotSpot Virtual Machine Garbage Collection Tuning Guide 。上面提到的这本书可以作为帮助我们理解的参考资料。这是我走过的弯路,以为 多看几遍这本jvm的书就能理解JVM的想法太天真了

文章来源:智云一二三科技

文章标题:一文就懂Java虚拟机的CMS收集器原理及使用

文章地址:https://www.zhihuclub.com/190736.shtml

关于作者: 智云科技

热门文章

网站地图