垃圾收集器必问系列—CMS

news2024/10/6 1:45:04

本文已收录至Github,推荐阅读 👉 Java随想录

应该相信,自己是生活的战胜者。——雨果

文章目录

    • CMS简介
    • 运作过程
    • CMS的缺陷
      • 处理器资源敏感
      • 无法处理“浮动垃圾”
      • 内存碎片

纵观全书《深入理解JVM虚拟机》第三版,在垃圾回收器这一篇章,对于CMS的笔墨是非常多的。CMS收集器是HotSpot虚拟机追求低停顿的第一次成功尝试,CMS 可以说是垃圾回收器的一个里程碑,其开启了 GC 回收器关注 GC 停顿时间的历史。

CMS简介

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器,启用参数:-XX:+UseConMarkSweepGC,使用的是标记-清除算法。在这之前的垃圾回收器,要么就是串行垃圾回收方式,要么就是关注系统吞吐量。而 CMS 垃圾回收器的出现,则打破了这个尴尬的局面。JDK9之后使用CMS垃圾收集器后,默认年轻代就为ParNew收集器,并且不可更改,同时JDK9之后被标记为不推荐使用,JDK14就被删除了。

CMS 垃圾回收器之所以能够实现对 GC 停顿时间的控制,其关键是三色标记算法(不了解的同学去翻我之前写的文章),通过三色标记算法,实现了垃圾回收线程与用户线程并发执行,从而极大地降低了系统响应时间。

运作过程

CMS整个过程分为四个步骤,包括:

  1. 初始标记(CMS initial mark)
  2. 并发标记(CMS concurrent mark)
  3. 重新标记(CMS remark)
  4. 并发清除(CMS concurrent sweep)

其中初始标记、重新标记这两个步骤仍然需要“Stop The World”

  • 初始标记仅仅只是标记一下GC Roots能直接关联到的对象,速度很快;
  • 并发标记阶段就是从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程是四个阶段中耗时最长的,但是不需要停顿用户线程,可以与垃圾收集线程一起并发运行;
  • 而重新标记阶段则是为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这里使用的是增量更新,这个阶段的停顿时间通常会比初始标记阶段稍长一些,但也远比并发标记阶段的时间短;
  • 最后是并发清除阶段,清理删除掉标记阶段判断的已经死亡的对象,由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的。

由于在整个过程中耗时最长的并发标记和并发清除阶段中,垃圾收集器线程都可以与用户线程一起工作,所以从总体上来说,CMS收集器的内存回收过程是与用户线程一起并发执行的。

CMS的缺陷

CMS有三个最大的缺点

处理器资源敏感

CMS收集器是比较消耗CPU资源的,对处理器资源是比较敏感的。在并发阶段,它不会导致用户线程停顿,但会占用了一部分线程(或者说处理器的计算能力)而导致应用程序变慢,降低总吞吐量。

低延迟和高吞吐,往往无法同时达成,低延迟有时是牺牲高吞吐换得的,有得必有失。

CMS默认启动的回收线程数是(处理器核心数量+3)/4,也就是说,如果处理器核心数在四个或以上,并发回收时垃圾收集线程只占用不超过25%的处理器运算资源。但是当处理器核心数量不足四个时,CMS对用户程序的影响就可能变得很大。如果应用本来的处理器负载就很高,还要分出一半的运算能力去执行收集器线程,就可能导致用户程序的执行速度忽然大幅降低。

为了缓解这种情况,虚拟机提供了一种称为“增量式并发收集器”(Incremental Concurrent Mark Sweep/i-CMS)的CMS收集器变种,在并发标记、清理的时候让收集器线程、用户线程交替运行,尽量减少垃圾收集线程的独占资源的时间,这样整个垃圾收集的过程会更长,但对用户程序的影响就会显得较少一些,直观感受是速度变慢的时间更多了,但速度下降幅度就没有那么明显。实践证明增量式的CMS收集器效果很一般,从JDK 7开始,i-CMS模式已经被声明为“deprecated”,即已过时不再提倡用户使用,到 JDK 9发布后i-CMS模式被完全废弃。

无法处理“浮动垃圾”

由于CMS收集器无法处理“浮动垃圾”(Floating Garbage),有可能出现“Con-current Mode Failure”失败进而导致另一次完全“Stop The World”的Full GC的产生。

在CMS的并发标记和并发清理阶段,用户线程是还在继续运行的,程序在运行自然就还会伴随有新的垃圾对象不断产生,但这一部分垃圾对象是出现在标记过程结束以后,CMS无法在当次收集中处理掉它们,只好留待下一次垃圾收集时再清理掉。这一部分垃圾就称为“浮动垃圾”。

由于在垃圾收集阶段用户线程还需要持续运行,那就还需要预留足够内存空间提供给用户线程使用,因此CMS收集器不能像其他收集器那样等待到老年代几乎完全被填满了再进行收集,在JDK5的默认设置下,CMS收集器当老年代使用了68%的空间后就会被激活。到了JDK 6时,CMS收集器的启动阈值就已经默认提升至92%,我们可以通过 -XX:CMSInitiatingOccupancyFraction 参数自行调节。

但这又会更容易面临另一种风险:要是CMS运行期间预留的内存无法满足程序分配新对象的需要,就会出现一次“并发失败”(Concurrent Mode Failure),这时候虚拟机将不得不启动后备预案:冻结用户线程的执行,临时启用Serial Old收集器来重新进行老年代的垃圾收集,但这样停顿时间就很长了。

内存碎片

CMS是一款基于“标记-清除”算法实现的收集器,在垃圾收集算法的时候我们说过,标记-清除会产生内存碎片。空间碎片过多时,将会给大对象分配带来很大麻烦,往往会出现老年代还有很多剩余空间,但就是无法找到足够大的连续空间来分配当前对象,而不得不提前触发一次Full GC的情况。

为了解决这个问题,CMS收集器提供了一个-XX:+UseCMS-CompactAtFullCollection开关参数(默认是开启的,此参数从JDK 9开始废弃),用于在CMS收集器不得不进行Full GC时开启内存碎片的合并整理过程,由于这个内存整理必须移动存活对象。这样空间碎片问题是解决了,但停顿时间又会变长,因此虚拟机设计者们还提供了另外一个参数-XX:CMSFullGCsBefore-Compaction(此参数从JDK 9开始废弃),这个参数的作用是要求CMS收集器在执行过若干次(数量由参数值决定)不整理空间的Full GC之后,下一次进入Full GC前会先进行碎片整理(默认值为0,表示每次进入Full GC时都进行碎片整理)。


如果本篇博客有任何错误和建议,欢迎给我留言指正。文章持续更新。

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

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

相关文章

CMakelists.txt简单介绍

先祝大家开工大吉,这篇策划一下CMakelists.txt,它依托在Cmake里,在大型工程、平台兼容方面非常好用的C项目编译工具,再此先对它做一个简短的介绍。 目录 一、CMakelists.txt简介 二、使用示例 三、总结 一、CMakelists.txt简介…

Eclipse swt环境搭建

通过Eclipse Marketplace安装打开eclipse,点击help,在弹出的框中,选择Eclipse Marketplace。如下所示。。。搜索windows 安装插件一、创建一个SWT项目点击左上角的File - > New -> Other...进入后搜索SWT ,选中在WindowBuilder下的SWT …

CnOpenData中国彩票销售数据

一、数据简介 彩票是一种编有号码的证券,按票面价格出售。开奖后,持有中奖号码奖券的,可按规定领奖。它是一种建立在机会均等基础上的、具有公平竞争特征的娱乐游戏。国家发行彩票的目的是筹集社会公众资金,资助福利、体育等社会公…

springboot中整合mybatis及简单使用

springboot中整合mybatis及简单使用1.引入依赖2.在applicaiton.yaml中配置数据源以及mybatis3.创建sql测试表4.编写mapper接口和mapper.xml文件4.1 mapper接口4.2 mapper.xml4.3 mybatisX快速开发插件5.创建service层和controller层5.1 创建service层5.2 创建controller层6.项目…

[网鼎杯 2018]Fakebook

目录 信息收集 代码审计 思路 解法一(非预期解) 解法二(预期解) 信息收集 目录扫描代码泄露扫描 robots.txt;flag.php;login.php;user.php;view.php;join.php; 直接打开flag.php后没有回显,应该需要通过ssrf来访…

Qt音视频开发12-easyplayer内核

一、前言 在视频监控行业经常看到两个厂家广告打得比较厉害,一个是青犀视频对应easyplayer,一个是大牛直播,两个最初都是sdk免费,并提供调用示例源码,后面大牛直播的sdk以及示例都无法运行,目前就剩下免费…

Word处理控件Aspose.Words功能演示:如何在 C# .NET 中将 PNG、JPG 转换为 Word

Aspose.Words 是一种高级Word文档处理API,用于执行各种文档管理和操作任务。API支持生成,修改,转换,呈现和打印文档,而无需在跨平台应用程序中直接使用Microsoft Word。此外, Aspose API支持流行文件格式处…

git push clone 参数具体解析

1 问题背景 git远程仓库有很多命令,但是教程里面讲解的都是特别模糊的。 2 命令实例解析 2.1 git branch -vv -a命令具体解析 在开始下面的命令解析之前,我们一定要学会git branch -vv -a这个命令,这个是查询本地仓库远程仓库跟踪关系最全…

《从0开始学大数据》之ZooKeeper是如何保证数据一致性的

背景 在分布式集群系统中,比如两个应用程序都需要对一个文件路径进行写操作,但是如果两个应用程序对于哪台服务器是主服务器的判断不同,就会分别连接到两个不同的 NameNode 上,并都得到了对同一个文件路径的写操作权限&#xff0…

振弦采集模块配置工具VMTool 扩展功能指令生成器与实时曲线

振弦采集模块配置工具VMTool 扩展功能指令生成器与实时曲线 指令生成器 ( 1) 指令生成 指令生成器可根据需要生成符合 MODBUS 和 AABB 通讯协议的读取和控制指令。 通过点击串口调试工具内的【 指令生成器】 按钮,可打开指令生成器窗口&#…

【SpringBoot高级篇】SpringBoot集成XXL-JOB分布式任务调度平台

【SpringBoot高级篇】SpringBoot集成XXL-JOB分布式任务调度平台简介下载源码部署任务调度平台执行SQL脚本部署任务平台简单使用初始化测试项目pom依赖SampleXxlJob修改配置调度平台配置执行器任务管理添加任务简介 XXL-JOB是一个分布式任务调度平台,其核心设计目标…

连续函数的运算与初等函数的连续性——“高等数学”

各位CSDN的uu们你们好呀,今天,小雅兰的内容是连续函数的运算与初等函数的连续性,上篇博客我们学到了函数的连续性和间断点,这篇博客相当于是上篇博客的一个补充,好吧,现在就让我们进入高等数学的世界吧 一、…

【刷题】不用加减乘除做加法

这是一道简单的数学题。但是比较繁琐,需要有耐心。 目录 前言 一、找规律 二、怎么实现加法? 总结 前言 这道题不让用四则运算符做加法,于是我第一反应是用位运算。 难道转成二进制再使用位运算吗,显然不需要,列草稿可…

Java 开发环境配置 “JDK”(超详细整理,适合新手入门)

前言 📜 “ 作者 久绊A ” 专注记录自己所整理的Java、web、sql等,IT技术干货、学习经验、面试资料、刷题记录,以及遇到的问题和解决方案,记录自己成长的点滴 目录 前言 一、什么是JDK? 1、大概介绍 2、详细介绍 …

MySQL进阶——触发器

1.触发器定义 同存储过程和函数类似,MySQL中的触发器也是存储在系统内部的一段程序代码,可以把它看作是一个特殊的存储过程。所不同的是,触发器无需人工调用,当程序满足定义条件时就会被MySQL自动调用。这些条件可以称为触发事件…

Weapp影视评分项目开发(04):三方组件的使用

知识点 三方组件库的安装与使用 computed 的安装与使用 新建代码分支 我们以 master 为基准,在 gitee 上新建代码分支 component,并在该分支上进行代码开发。命令如下: git pull // 拉取 component 分支 git checkout component // 切换到…

哪款无线耳机音质好?发烧友推荐四大音质超好的蓝牙耳机

蓝牙耳机因为摆脱了线的束缚,使用起来会更方便,近几年在人们的日常生活中也越来越常见。哪款无线耳机音质好?在此,我来给整理了几款发烧友都在推荐的好音质蓝牙耳机,一起来看看吧。 一、南卡小音舱蓝牙耳机 售价&…

推荐系统之ABTest实验中心

5.3 ABTest实验中心 学习目标 目标 无应用 无 个性化推荐系统、搜索引擎、广告系统,这些系统都需要在线上不断上线,不断优化,优化之后怎么确定是好是坏。这时就需要ABTest来确定,最近想的办法、优化的算法、优化的逻辑数据是正向…

Linux | 人生苦短,我用Vim【最受欢迎的编辑器】

一探顶级编辑器——Vim一、初次见面,你好vim1、vim的基本概念2、IDE与编辑器的区别3、vim中的五种常见模式介绍二、初出茅庐,vim基本操作1、安装vim,进入vim2、vim中的模式切换📺三、初露锋芒,vim指令集1、&#x1f52…

数据库系统概论——关系代数详解

文章目录1、关系代数概述1.1 传统的集合运算1.2 专门的关系运算1.2.1 选择运算1.2.2 投影(Projection)1.2.3 连接(Join)1.2.4 两类常用连接运算1.2.5 除(Division)1、关系代数概述 关系代数是一种抽象的查…