JVM垃圾回收——CMS垃圾收集器
创始人
2024-02-11 18:33:35
0

目录

一、什么是CMS垃圾收集器

二、CMS垃圾收集的过程

三、CMS收集器的不足

四、CMS收集器的参数配置


一、什么是CMS垃圾收集器

        虽然HotSpot虚拟机已经在jdk14中移除了CMS垃圾收集的参数,但是考虑到还有很多开发是基于jdk8开发的,所以还是有必要了解一下CMS垃圾收集器的。CMS(Concurrent Mark Sweep)收集器是一种基于标记清除算法,追求最短停顿时间的真正意义上的第一款并发垃圾收集器。

二、CMS垃圾收集的过程

        

         从上面的图上可以看出,CMS垃圾收集器需要经过初始标记、并发标记、重新标记、并发清除四个阶段。

        初始标记只是标记一下GC Roots能直接关联到的对象,速度很快,这个过程需要STW。

        并发标记就是从GC Roots开始遍历整个对象引用的过程,这个阶段时间较长,但是适合用户线程并发执行的不需要停顿用户线程,这个过程不需要STW。

        重新标记阶段是为了修正并发标记期间,因为用户线程执行而导致标记产生变动(错标、漏标)哪一部分对象(具体的内容可以参考JVM垃圾回收——三色标记法_熟透的蜗牛的博客-CSDN博客),这个阶段停顿时间通常比初始标记时间长,但也远比并发标记时间短,这个过程也需要进行STW。

        并发清除阶段是清理删除标记阶段已被判处死亡的对象,由于基于清除算法,不需要移动存活对象,这个阶段可以和用户线程并发执行。

三、CMS收集器的不足

        仔细想一下CMS虽然是一个和用户线程并发执行的收集器,不需要停顿用户线程或许你会认为这个效果还是挺好的,你这样想那就格局有点小了,虽然在并发阶段不会导致用户线程的停顿,但却占用了CPU,导致用户的应用变慢,导致应用的吞吐量下降,这就是CMS收集器的第一个不足之处,对处理器资源非常敏感。CMS默认启动的回收线程数为(处理器(CPU)核心数+3)/4 ,也就是说如果CPU的核心数在四个或者四个以上,并发回收的垃圾收集线程占用不少于1/4的CPU资源。假设我的服务器是2核的,那么(2+3)/4=1,需要一半的核心数来处理垃圾收集,那这样是个不能接受的问题。

        在CMS并发标记和并发清除阶段,用户线程还是活跃的,自然也会产生新的垃圾对象,那么这些垃圾对象就只能等到下一次垃圾回收的时候才能进行清除,这一部分我们叫做“浮动垃圾”。同样因为并发收集垃圾的原因,CMS收集器需要预留足够的内存空间来存储新的对象,所以CMS收集器并不能像其他收集器一样等到老年代几乎满了之后才会回收垃圾。在jdk5默认当老年代使用达到68%的空间后就会进行垃圾清除,而在jdk6之后这个默认值设定为92%。这个参数可以通过JVM参数-XX:CMSInitiatingOccupancyFraction参数来设定。如果这个值设置的过小垃圾回收就相对频繁,如果设置的过大就会产生“并发失败”(Concurrent Mode Failure),如果出现并发失败,那么JVM就不得不暂停用户线程,临时启用Serial Old收集器来重新进行老年代的回收,这样整个垃圾回收过程就会停顿很长的时间。因此这个值需要在实际生产过程中根据实际情况配置,这是CMS收集器的二一个不足之处。

        三一个不足之处就是CMS是基于标记-清除的算法实现的垃圾收集器,所以CMS垃圾收集会产生大量的空间碎片,由于大量的空间碎片的产生,当分配大对象找不到足够的空间时,就不得不提前进行一次Full GC。为了解决这个问题JVM提供了参数-XX:+UseCMSCompactAtFullCollection参数,这是一个开关参数,默认是开启的,在jdk9之后废弃。

四、CMS收集器的参数配置

测试代码

package com.wssnail.test;import java.util.ArrayList;
import java.util.List;/*** @author 熟透的蜗牛* @version 1.0* @description: 测试CMS垃圾收集器* @date 2022/11/9 21:56*/
public class TestCMSGc {private static String[] strArr = new String[]{"中国人民万岁", "梅西好样的,梅西好样的梅西好样的梅西好样的梅西好样的梅西好样的梅西好样的梅西好样的", "我爱看世界杯,我爱看世界杯我爱看世界杯我爱看世界杯我爱看世界杯我爱看世界杯我爱看世界杯我爱看世界杯我爱看世界杯"};public static void main(String[] args) {List list = new ArrayList<>();for (int i = 0; i < 100000; i++) {try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}list.add(strArr);}while (true) {}}
}

       Jvm参数配置

-Xmx20M
-Xms20M
-Xmn6M
-XX:+PrintGCDetails
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=60
-XX:+UseCMSCompactAtFullCollection
-XX:+PrintCommandLineFlags

 打印出明细如下

-XX:CMSInitiatingOccupancyFraction=60 
-XX:InitialHeapSize=20971520 
-XX:MaxHeapSize=20971520 
-XX:MaxNewSize=6291456 
-XX:MaxTenuringThreshold=6 
-XX:NewSize=6291456 
-XX:OldPLABSize=16 
-XX:+PrintCommandLineFlags 
-XX:+PrintGCDetails 
-XX:+UseCMSCompactAtFullCollection 
-XX:+UseCompressedClassPointers 
-XX:+UseCompressedOops 
-XX:+UseConcMarkSweepGC 
-XX:-UseLargePagesIndividualAllocation 
-XX:+UseParNewGC

-XX:+UseParNewGC,-XX:MaxTenuringThreshold=6 ,可以看出 如果配置了CMS垃圾收集器,默认新生代使用的是ParNewGC收集器,并且复制的次数为6次时会进入老年代,如下两张图

第六次复制

 第七次复制可以看到老年代由2.030M到2.160M

 其他的具体细节,请感兴趣的朋友自己动手实验一下,观察一下CMS垃圾收集的过程。    

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...