深入浅出CMS垃圾收集器

深入浅出CMS垃圾收集器如果说 JDK1 8 是最常用的线上版本 那么 CMS 垃圾回收器就是最常用的老年代垃圾回收器

本文收录于JavaStarter ,里面有我完整的Java系列文章,学习或面试都可以看看

(一)CMS垃圾收集器

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的老年代收集器。CMS是基于标记-清除算法的老年代垃圾回收器,CMS是目前应用最广泛的老年代垃圾回收器。

CMS的使用只需要在JVM的启动参数中增加(-XX:+UseConcMarkSweepGC)参数即可激活使用CMS垃圾收集器。

CMS基于“标记-清除”算法实现,是HotSpot虚拟机的第一款真正意义上的并发收集器,基本上实现了垃圾收集线程与用户线程同时工作。

(二)CMS垃圾收集器的步骤

CMS的运行过程主要分为四个阶段:

1、初始标记:标记GC Roots可以直接关联到的对象,速度很快(stop the world)

2、并发标记:根搜索算法的过程

3、重新标记:为了修正并发标记期间,因程序运行导致标记产生变动的对象。(stop the world)

4、并发清除:清除垃圾

我画了一个图更加形象地展示上面四个流程,红色表示CMS线程,黄色表示应用线程

深入浅出CMS垃圾收集器

(三)CMS垃圾收集器的优缺点

CMS垃圾收集器的主要有点为并发收集、并发清除、低停顿。相比较前几代的垃圾收集器,CMS垃圾收集器给用户的体验更好,因为它追求的是最短的回收停顿时间。

CMS垃圾回收器的缺点也比较明显:

1、对CPU资源十分敏感,因为并发标记和并发清除都是和程序同时运行,因此会占用CPU导致应用程序变慢。

2、无法处理浮动垃圾,浮动垃圾就是在并发清除过程中新生成的垃圾,这部分垃圾CMS无法在本次被清理,可能出现Concurrent Mode Failed报错,因此需要预留一定的内存空间,无法等到老年代快被占满时再清除。默认情况下,CMS在老年代使用了92%后就会被激活。可以设置-XX:CMSInitiatingOccupancyFraction设置这个值。

如果真的出现了concurrent mode failed,说明已经没办法并发标记垃圾了,这时候就会使用serial old垃圾收集器来回收,也就是通过stop the world的方式。

3、产生空间碎片,由于采用的是标记-清除算法,那就无法避免会产生空间碎片的问题,这会给分配大对象带来困难。

(四)CMS的相关参数

我把常用的几个参数列了出来,每个参数表示什么意思也都写在了最后:

1-XX:+UseConcMarkSweepGC #启动CMS 2-XX:ConcGCThreads #CMS并发线程数量 3-XX:+UseCMSCompactAtFullCollection #FullGC之后做压缩,减少碎片 4-XX:CMSFullGCsBeforeCompaction #多少次FullGC之后压缩一次碎片,默认0,表示每次FullGC后都会压缩 5-XX:CMSInitiatingOccupancyFraction #老年代使用多少后会触发FullGC,默认92 6-XX:+UseCMSInitiatingOccupancyOnly #固定使用CMSInitiatingOccupancyFraction设置的参数, 如果不设置该参数,CMSInitiatingOccupancyFraction设置的比例只会在第一次GC时使用,后续会自动优化 7-XX:+CMSScavengeBeforeRemark #在CMS GC之前触发一次minor gc,降低CMSGC标记阶段的开销 8-XX:+CMSClassUnloadingEnabled CMS收集器默认不会对永久代进行垃圾回收。如果希望对永久代进行垃圾回收,可用设置标志 

以上参数在使用时根据业务的需要以及机器配置等进行综合考虑后设置。

我这里给出一个微服务架构下线上单个服务的JVM参数,参数设置仅供参考,不同的业务场景下设置都不同。:

-Xmx4096m -Xms4096m -Xmn2048M -XX:HeapDumpPath=/home/admin/logs/java.hprof -XX:+HeapDumpOnOutOfMemoryError -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=80 -XX:+CMSClassUnloadingEnabled -Xloggc:/home/admin/logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps 

(五)总结

首先用一句话总结CMS垃圾收集器:以获取最短回收停顿时间为目标的老年代收集器,收集过程主要分为初始标记、并发标记、重新标记、并发清除四个阶段,缺点是对CPU资源十分敏感、无法处理浮动垃圾、产生空间碎片

如果说JDK1.8是最常用的线上版本,那么CMS垃圾回收器就是最常用的老年代垃圾回收器。因此知道CMS不管对工作还是面试都是有很大帮助的,我是鱼仔,我们下期再见!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/233530.html原文链接:https://javaforall.net

(0)
上一篇 2025年7月11日 下午3:01
下一篇 2025年7月11日 下午3:22


相关推荐

  • Visio2013 Professional专业版密钥

    Visio2013 Professional专业版密钥Visio2013密钥专业版:VisioProfessional2013KEYC2FG9-N6J68-H8BTJ-BW3QX-RM3B32NYF6-QG2CY-9F8XC-GWMBW-29VV8FJ2N7-W8TXC-JB8KB-DCQ7Q-7T7V3VXX6C-DN3HQ-3CRXG-RF4KT-YG7V3B3C7Q-D6NH2-2VRFW-HHWDG-FVQB6转载自:https://blog.csdn.net/alittleyatou/article/detail.

    2022年6月24日
    66
  • clion永久激活码[最新免费获取]

    (clion永久激活码)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~6EK6WKOHUX-eyJsaWNlbnNlSWQiOi…

    2022年3月28日
    62
  • 在Pycharm安装库时,报错提示:python中的pip版本过低。「建议收藏」

    在Pycharm安装库时,报错提示:python中的pip版本过低。「建议收藏」但是在执行更新pip指令:python-mpipinstall–upgradepip后。直接在cmd中输入指令后,显示:在anaconda中的pip版本已经是最高了。此时应该进入python文件夹中执行更新pip的指令。在指令执行前pip的版本:执行指令:执行后:…

    2022年8月27日
    8
  • MyEclipse10.6 安装SVN插件方法及插件下载地址

    MyEclipse10.6 安装SVN插件方法及插件下载地址方法一:在线安装1.打开HELP->MyEclipseConfigurationCenter。切换到SoftWare标签页。 2.点击AddSite打开对话框,在对话框Name输入Svn,URL中输入:http://subclipse.tigris.org/update_1.6.x3.在左边栏中找到PersonalSite中找到SVN展开。将Core

    2022年7月20日
    18
  • 补码 转换_三线8译码器有什么型号

    补码 转换_三线8译码器有什么型号补码转换`timescale1ns/10psmoduledevice(a,a_comp);input[7:0]a;//括号要写在前面output[7:0]a_comp;wire[6:0]b;//按位取反的幅度位wire[7:0]y;//负数的补码assignb=~a[6:0];assigny[6:0]=b+1;//按位取反再加1assigny[7]=a[7];//符号位不变assigna_comp=a[7]?y:a;//二选一endmodulemodule

    2025年12月14日
    5
  • taskkill java进程_windows – Taskkill / f不会杀死进程

    taskkill java进程_windows – Taskkill / f不会杀死进程windows Taskkill f 不会杀死进程当我从 VS 启动 VS 的实验实例进行调试并停止调试时 有时直接从父 VS zombiledeven exe 进程仍在运行 我无法杀死 它坚持我的许多 dll 当我以管理员身份登录这台 64 位 Win7 机器时 我希望能够杀死我想要的任何进程 Itried fromAdminist EndTask

    2026年3月16日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号