JVM基础(8)——CMS垃圾回收器

news2024/11/18 5:34:58

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析

阶段4、深入jdk其余源码解析

阶段5、深入jvm源码解析

一、简介

理想情况下,我们都希望自己的系统能在每次Minor GC后,存活对象都能转移到Survivor区,避免进入老年代。但真实情况是,线上系统很可能因为各种各样的情况,导致很多对象进入老年代,甚至频繁触发老年代的Full GC。所以,我们必须对老年代的垃圾回收器的执行原理有一个清晰的认识,才能在出现问题时及时应对。

二、CMS基本原理

老年代的垃圾回收,我们一般会选择CMS垃圾回收器,它采用的是 标记清除(mark-sweep) 算法。关于标记清除算法,我们已经在JVM垃圾回收算法一文中详细介绍过了标记清除算法,标记清除与标记整理的区别就是它标记完垃圾对象后直接清理掉,这个会造成内存碎片过多的问题,后面会讲到。

针对老年代进行垃圾回收时,CMS也会出现”Stop the World“现象,之前的文章也说过,如果挂起一切工作线程,然后慢慢地去执行”mark-sweep“算法,会导致系统”卡顿“时间过长,很多响应无法处理。CMS采取的策略是: 垃圾回收线程和系统工作线程尽量并行执行 。

CMS在执行一次垃圾回收的过程一共为4个阶段:

  • 初始标记
  • 并发标记
  • 重新标记
  • 并发清理

下面我们来对每一阶段进行分析。

2.1 初始标记

CMS进行垃圾回收时,首先会执行初始标记,这个阶段会让系统的工作线程全部挂起,进入“Stop the World”状态,初始标记,就是标记“GC Roots”能够引用到的对象。如下图:

我们还是以示例代码来看下整个过程:

    public class Kafka {
        public static ReplicaManager replicaManager = new ReplicaManager();
    }
    public class ReplicaManager {
        public ReplicaFetcher replicaFetcher = new ReplicaFetcher();
    }

假设上面代码对应的JVM内存结构如下图:

那么初始标记时,静态变量replicaManager所引用的ReplicaManager对象就会被标记出来,但ReplicaFetcher对象不会被标记,因为类的静态字段和方法的局部变量可以作为“GC Roots”,而类的普通实例字段不能。

初始标记阶段,虽然会出现“Stop the World”,但其实影响不大,因为从“GC Roots”去标记存活对象的效率很高。另外, 可以通过设置参数-XX:+CMSParallelInitialMarkEnabled开始多线程的初始标记,减少STW时间,以提升性能。

2.2 并发标记

接着,进入并发标记阶段,该阶段系统的工作线程可以随时创建各种对象。与此同时,垃圾回收线程会尽可能的对已有的对象进行GC Roots追踪。

所谓GC Roots追踪,就是对老年代里的ReplicaFetcher这类对象,看看被谁引用了?比如ReplicaFetcher对象被ReplicaManager对象的replicaFetcher字段引用,而ReplicaManager对象又被Kafka类的静态字段replicaManager引用。

那么此时,CMS就会认为ReplicaFetcher这个对象其实是被GC Roots间接引用的,所以不需要回收它,可以把它标记存活,如下图:

但是在并发标记的过程中,由于系统在不停的工作,可能会创建出来新的对象,也可能一些旧的对象失去引用,如下图:

并发标记的时候,需要对GC Roots进行深度追踪,看所有对象里到底有多少是存活的,而老年代中的对象存活率又比较高,所以这个过程会追踪大量的对象,比较耗时。

并发标记阶段,其本质就是追踪老年代中的所有对象能否直接或间接被GC Roots引用,这个过程是跟垃圾回收线程并行进行的,所以虽然很耗时,但不会对系统运行造成较大影响。

2.3 重新标记

在第二阶段,一边是GC线程标记着存活对象和垃圾对象,另一边是工作线程不停的创建新对象和让老对象失去引用,所以当第二阶段结束后,会有很多存活对象和垃圾对象是没有被标记出来的:

所以,重新标记阶段的工作,就是让系统停下来,进入“Stop the World”,然后再重新标记一下第二阶段里新创建和新失去引用的那些对象:

重新标记阶段,虽然会发生“Stop the World”,但速度是很快的,因为只是对第二阶段中因为并行而变动过的少数对象进行标记。另外,可以通过设置参数-XX:+CMSScavengeBeforeMark,让重新标记之前尽量先先执行一次Young GC,那么重新标记的时候就可以少扫描一些对象,以提升该阶段的性能。

2.4 并发清理

重新标记完成后,就会恢复工作线程,进入最后的并发清理阶段。该阶段垃圾回收线程和工作线程是并行运行的,垃圾回收线程会清理之前标记为垃圾的对象:

并发清理需要将垃圾对象从各种随机的内存位置清理掉,所以也比较耗时。

并发清理阶段和并发标记阶段一样,是比较耗时的,但是不会挂起工作线程,所以基本不影响系统的运行。

三、性能问题

CMS为了避免长时间的”Stop the World“,采用了4个阶段进行垃圾回收,其中初始标记和重新标记阶段虽然会”Stop the World“,但是耗时很短,所以影响不大;并发标记和并发清理阶段虽然耗时较长,但是可以跟工作线程并行执行,所以影响也不大。

那么,CMS就很完美了吗?显示不是,我们来看下CMS的这种垃圾回收方式可能会出现什么样的问题。

3.1 CPU消耗

CMS垃圾回收器有一个最大的问题,就是并发标记和并发清理阶段,工作线程和垃圾回收线程同时运行,而这两个阶段又比较耗时,所以会导致有限的CPU资源长时间被垃圾回收线程占用。

CMS启动时默认的垃圾回收线程数量是:(CPU核数+3)/4。假设我们用最普通的机器(2核4G)来测算,(2+3)/4=1,也就是说GC线程会占去一个CPU。

3.2 Concurrent Mode Failure

CMS垃圾回收器的另一个问题就是Concurrent Mode Failure。所谓 Concurrent Mode Failure,就是指在并发清理阶段,有一些原来是新生代的对象将晋升到老年代,而此时老年代的可用空间又不够了,就会发生Concurrent Mode Failure。我们来看下整个过程:

首先,在并发清理阶段,由于工作线程也在并行运行,一些新生代对象晋升到了老年代,随后失去了引用,那这些对象就变成了老年代的” 浮动垃圾 “,因为它们已经错过了并发标记,只能等到下一次GC时被回收:

上图中的红圈部分就是一个浮动垃圾。为了应对出现”浮动垃圾“这种情况,CMS会在老年代预留一定的空间,如果CMS在垃圾清理期间,出现了浮动垃圾,且垃圾大小大于老年代中的预留空间,就会出现Concurrent Mode Failure

当出现Concurrent Mode Failure时,CMS会自动让Serial Old垃圾收集器来替代自己,强行进行“Stop the World”,并重新进行GC Roots追踪,标记垃圾对象并清除,完事后才恢复工作线程运行。

综上,生产环境下,这个自动触发CMS垃圾回收的比例需要合理优化下,避免出现Concurrent Mode Failure问题。

CMS触发垃圾回收的时机,其中一个就是当老年代内存占用达到一定的比例,通过 -XX:CMSInitiatingOccupancyFaction参数可以设置这个比例,JDK1.6中默认是92%。

3.3 内存碎片

由于CMS采用标记整理算法对老年代的垃圾对象进行回收,所以会产生大量的内存碎片。如果内存碎片太多,会导致后续对象进入老年代找不到可用的连续空间,触发Full GC。

CMS有一个参数-XX:+UseCMSCompactAtFullCollection(默认打开),表示是否要在Full GC之后进行Stop the World,停止工作线程,然后进行老年代的内存碎片整理。

还有另外一个参数-XX:CMSFullGCsBeforeCompaction,意思是执行多少次Full GC之后再执行一次内存碎片整理工作,默认是0,即每次Full GC之后都会进行一次内存碎片整理。

四、总结

通过上述对CMS垃圾回收器的执行流程分析,我们其实已经知道CMS专门针对“Stop the World”进行了优化:

  • 最耗时的两个阶段——并发标记和并发清理,其实都不需要挂起工作线程,所以对系统整体性能影响不大;
  • 两个需要”Stop the World“的阶段——初始标记和重新标记,仅仅是简单的标记而已,速度非常快,所以基本上对系统的整体性能影响也不大。

但是,用CMS进行老年代的垃圾回收还是要比新生代的Minor GC慢十倍以上,原因很简单:

  • 新生代执行速度快,是因为新生代的存活对象很少,从GC Roots出发马上能追踪到哪些对象是活的,压根不需要追踪多少对象;
  • 老年代中对象的存活率很高,所以并发标记阶段很慢,此外并发清理阶段是去找各种零零散散的垃圾对象,速度也很慢,最后Full GC完还得内存整理,所以非常耗时。

我们这里对 Full GC的所有情况 做一个总结:

  1. 老年代的可用连续内存空间 < 新生代全部对象的大小,且未开启空间担保;
  2. 老年代的可用连续内存空间 < 新生代全部对象的大小,且开启了空间担保,但是老年代的可用连续内存空间<历代晋升到老年代的平均对象大小;
  3. 新生代Minor GC后,存活对象大小 > Survivor大小,而老年代的可用连续内存空间不足;
  4. 老年代已经使用的内存空间超过了-XX:CMSInitiatingOccupancyFaction参数指定的比例。

最后,CMS也存在一些问题,比如CPU消耗、Concurrent Mode Failure、内存碎片等,需要通过一些参数进行合理配置,我们后面章节会通过案例进行讲解如何优化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1386290.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

企业销售人员都在用的客户管理CRM软件有哪些?

“目前我公司需要用到软件的人数不超过10个&#xff0c;主要销售模式是电话、拜访为主&#xff0c;产品是称重设备&#xff0c;客户是工厂。” 上面的需求整理了一下&#xff1a; 团队规模&#xff1a;小规模&#xff0c;不超过10人——尽可能降低使用成本使用人员&#xff1a;…

C++结合OpenCV:图像的加法运算

一、图像运算 针对图像的加法运算、位运算都是比较基础的运算。但是&#xff0c;很多复杂的图像处理功能正是借助这些基础的运算来完成的。所以&#xff0c;牢固掌握基础操作&#xff0c;对于更好地实现图像处理是非常有帮助的。本章简单介绍了加法运算、位运算&#xff0c;并…

CG Magic分享3dmax渲染太亮问题如何解决?

3D Max软件渲染时&#xff0c;渲染问题较多也是正常的&#xff0c;对于行业小白来说&#xff0c;渲染问题多也是能理解的&#xff0c;因为&#xff0c;小编经常在问答中&#xff0c;看到一些网友提问&#xff0c;3dmax渲染太亮怎么办&#xff1f; 3dmax渲染太亮了怎么回事&…

如何定位和优化程序CPU、内存等性能之巅

摘要 性能优化指在不影响系统运行正确性的前提下&#xff0c;使之运行得更快&#xff0c;完成特定功能所需的时间更短&#xff0c;或拥有更强大的服务能力。本文将介绍性能优化的基本概念以及如何定位和优化程序中的CPU、内存和IO瓶颈。 引言 随着计算机系统的日益复杂和应用…

有哪些windows录屏软件?

有哪些windows录屏软件&#xff1f;随着技术的发展&#xff0c;使用Windows录屏软件已成为一种非常方便的方式&#xff0c;可以帮助人们记录和分享他们在计算机上的操作过程。例如&#xff0c;您可以使用录屏软件记录您在编辑文档或演示新产品时的屏幕操作&#xff0c;并将其用…

BIOS知识枝桠——RAID 磁盘阵列

文章目录 前言一、RAID介绍二、RAID等级分类1.RAID02.RAID13.RAID24.RAID3和RAID45.RAID5和RAID66.RAID77.RAID10 BIOS下组建RAID 前言 假设存在多块磁盘&#xff0c;如果不组建阵列&#xff0c;磁盘与磁盘之间是没有任何关系的。磁盘A和B&#xff0c;放在A中的文件与B磁盘没有…

自学Python笔记总结(更新中……)

自学Python笔记总结 网址数据类型类型查看类型&#xff0c;使用type内置类标识符 输出输入语句format函数的语法及用法数据类型的转换运算符算数运算符赋值运算符的特殊场景拆包 比较运算符逻辑运算符 与 短路位运算符运算符优先级 程序流程控制分支语句pass 占位 循环语句 whi…

可应用于电脑主板等产品上的精密基准电路WL431 输出电压可设定 响应速度快

WL431为三端可调节精密基准源。通过两个外接电阻&#xff0c;输出电压可在Vref约2.5 V )到36V连续调节。该电路输出阻抗小(0.2Q)。 开启特性好&#xff0c;在许多应用场合&#xff0c;它能较好地替换齐纳极管。 主要特点&#xff1a;● 温度系数 50pmC ● 在…

荣耀开发者大会2023 · 一张图读懂智慧人机交互分论坛

荣耀智慧人机交互&#xff0c;以用户意图理解为主的智慧交互&#xff0c;平台级AI使能主动理解用户意图&#xff0c;服务找人能力全面升级&#xff01; 荣耀智慧门能精准理解用户交互意图&#xff0c;覆盖100头部应用&#xff0c;支持文本、图片等元素类型随心拖拽&#xff0c…

自媒体必备的8个素材网站,免费可商用。

自媒体必备的8个素材网站&#xff0c;视频、音效、音频、图片等素材非常齐全&#xff0c;免费下载&#xff0c;无需担心侵权&#xff0c;赶紧收藏起来吧~ 视频素材 1、菜鸟图库 https://www.sucai999.com/video.html?vNTYwNDUx 菜鸟图库可以找到设计、办公、图片、视频、音频…

基于树莓派5(Raspberry Pi 5)的高性能工业平板电脑升级版!

​ 上海晶珩继推出首个搭载 Raspberry Pi 5 的平板电脑ED-HMI3010系列后&#xff0c;又推出了具备高性能和多功能特性的 Raspberry Pi 5 的平板电脑ED-HMI3020系列。ED-HMI3020支持选择7英寸和10.1英寸两种尺寸的触摸屏&#xff0c;可选配 M.2 NVMe SSD 存储扩展&#xff0c;提…

new mars3d.graphic.PolygonEntity({计算平面几何中心点及贴地效果展示

1.Mars3d提供了几何图形相关点位的计算方法polyutil&#xff1a; PolyUtil - V3.7.0 - Mars3D API文档 2.通过api可以算出相关经纬度坐标&#xff0c;实现相关中心点的展示 &#xff1a; 功能示例(Vue版) | Mars3D三维可视化平台 | 火星科技 3.相关实现代码&#xff1a; fu…

HCIP的静态路由复习

VRP设置用户名密码登录 [R1]aaa [R1-aaa]local-user TMG password cipher huawei #创建一个名TMG的用户&#xff0c;密码huawei Info: Add a new user.[R1-aaa]local-user TMG privilege level 15 #设置权限 [R1-aaa]local-user TMG service-type terminal …

个性化定制的知识付费小程序,为用户提供个性化的知识服务

明理信息科技知识付费saas租户平台 随着知识经济的兴起&#xff0c;越来越多的人开始重视知识付费&#xff0c;并希望通过打造自己的知识付费平台来实现自己的知识变现。本文将介绍如何打造自己的知识付费平台&#xff0c;并从定位、内容制作、渠道推广、运营维护四个方面进行…

恒温器探针样品座

恒温器探针样品座是一种用采用可移动探针完成恒温器电缆和被测样品的电学连接&#xff0c;避免了每次样品电引线的焊接&#xff0c;探针可移动&#xff0c;5mm--20mm大小的样品均可适用&#xff0c;探针可以安装6个&#xff0c;标准配置探针数量为4个。 恒温器探针样品座由T型…

安装tesseract

Tesseract OCR是一款由HP实验室开发由Google维护的开源OCR引擎&#xff0c;在字符识别领域发挥着举足轻重的作用。除了使用软件自带的中英文识别库&#xff0c;我们可以使用Tesseract OCR训练属于自己的字库。 下载地址&#xff1a;https://digi.bib.uni-mannheim.de/tesseract…

自动化革命:大象机器人的Mercury A1机械臂

引言 大象机器人的Mercury系列&#xff0c;是面向工业自动化和智能制造的新型机械臂产品线。这些机械臂不仅在设计上创新&#xff0c;还在材料选择上使用了碳纤维、铝合金和工程塑料等轻质强韧材料&#xff0c;搭载高精度谐波减速器。Mercury系列的推出&#xff0c;反映了大象机…

【CSS】解决height = line-height 文字不垂直居中(偏上、偏下)的问题

解决办法1&#xff1a; 查看 font-family 属性&#xff0c;确认是否是因为字体而导致的不垂直居中问题。 其他小知识&#xff1a; 基线就是小写x字母的下边缘(线) 就是我们常说的 基线。line-height 属性设置的行高也就是定义的两行文字基线之间的距离! 参考文章&#xff1a;…

为什么单片机上的程序不怎么使用malloc,而PC上经常使用?

为什么单片机上的程序不怎么使用malloc&#xff0c;而PC上经常使用&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「单片机的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿…

数字保险箱:揭秘迅软DSE企业加密系统,助您信息安全无忧!

在当今时代&#xff0c;数据泄露危机和各种网络攻击已成为企事业单位所面临的首要威胁。在这个背景下&#xff0c;企业加密系统如同一把强大的“保护伞”&#xff0c;为海量企业提供了至关重要的防护。那么&#xff0c;究竟是什么原因&#xff0c;使得企业加密系统能够成为抵抗…