死磕CMS垃圾回收器

news2024/12/27 17:49:28

为什么会有这篇文章?
**校招垃圾回收面试重灾区。**本人秋招面试过大大小小的公司,发现几乎所有公司在面试的时候,一旦涉及到JVM只是,CMS和G1是常问点,而且CMS问的尤其多。所以本文会对根据网上常见的资料做一个整合并根据自己面试过程中遇到的一些问题对CMS进行一些本质上的剖析。
**知识沉淀。**网上很多资料可能知识介绍可能很浅,只介绍CMS流程和优缺点,但是没有讲CMS怎么做到低停顿时间,以及和parallel scavenge在吞吐量方面的对比。本文想对这点进行相应的解答。

一. 思维导图

二. Parallel Scavenge

什么是Parallel Scavenge

与 ParNew 一样是多线程收集器
其它收集器关注点是尽可能缩短垃圾收集时用户线程的停顿时间,而它的目标是达到一个可控制的吞吐量,它被称为“吞吐量优先”收集器。这里的吞吐量指 CPU 用于运行用户代码的时间占总时间的比值。
停顿时间越短就越适合需要与用户交互的程序,良好的响应速度能提升用户体验。而高吞吐量则可以高效率地利用 CPU 时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务
缩短停顿时间是以牺牲吞吐量和新生代空间来换取的: 新生代空间变小,垃圾回收变得频繁,导致吞吐量下降。
可以通过一个开关参数打开 GC 自适应的调节策略(GC Ergonomics),就不需要手动指定新生代的大小(-Xmn)、Eden 和 Survivor 区的比例、晋升老年代对象年龄等细节参数了。虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量。

老年带对应的事Parallel old
image.png
只需要记住关键字:多线程、吞吐量优先、jdk 1.8 默认、可自适应调节

优缺点

优点:高吞吐量
缺点:

  • 垃圾回收时停顿时间可能过长:因为优先考虑了吞吐量,所以停顿时间可能会过长
  • 不适合交互式的任务:因为停顿时间长
  • 可能占用的内存比较高(为了保证高吞吐量):内存大,发生gc少,吞吐量高;但是因为内存大,单次gc复制算法时间复杂度高。

三. CMS

什么是CMS

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。它非常符合在注重用户体验的应用上使用。

CMS(Concurrent Mark Sweep)收集器是 HotSpot 虚拟机第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程(基本上)同时工作。

CMS流程

需要注意的是老年代的收集采用的 **标记清除 **算法
image.png

  • 初始标记: 暂停所有的其他线程,并记录下直接与 root 相连的对象,速度很快 ;
  • 并发标记: 同时开启 GC 和用户线程,用一个闭包结构去记录可达对象。但在这个阶段结束,这个闭包结构并不能保证包含当前所有的可达对象。因为用户线程可能会不断的更新引用域,所以 GC 线程无法保证可达性分析的实时性。所以这个算法里会跟踪记录这些发生引用更新的地方。
  • 重新标记: 重新标记阶段就是为了修正并发标记期间因为用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段的时间稍长,远远比并发标记阶段时间短
  • 并发清除: 开启用户线程,同时 GC 线程开始对未标记的区域做清扫。

优缺点

优点:低停顿时间、并发清除
缺点:

  • 吞吐量低: 低停顿时间是以牺牲吞吐量为代价的,导致 CPU 利用率不够高。
  • 无法处理浮动垃圾,可能出现 Concurrent Mode Failure。浮动垃圾是指并发清除阶段由于用户线程继续运行而产生的垃圾,这部分垃圾只能到下一次 GC 时才能进行回收。由于浮动垃圾的存在,因此需要预留出一部分内存,意味着 CMS 收集不能像其它收集器那样等待老年代快满的时候再回收。如果预留的内存不够存放浮动垃圾,就会出现 Concurrent Mode Failure,这时虚拟机将临时启用 Serial Old 来替代 CMS。
  • 标记 - 清除算法导致的空间碎片,往往出现老年代空间剩余,但无法找到足够大连续空间来分配当前对象,不得不提前触发一次 Full GC。

为什么采用标记清除算法

明明其他大多数垃圾回收器老年代都采用标记整理算法,为什么CMS要另辟蹊径采用标记清除?
标记清除速度快,但是会产生内存碎片
标记整理可以解决内存碎片问题,但是缺点就是整理移动的过程比较耗费时间。
在标记整理算法中,首先进行标记阶段,标记出所有存活的对象,然后进行整理阶段,将存活的对象向一端移动,然后释放整理后的空间。这个过程中,需要移动对象,可能会导致大量的内存复制和对象移动操作,对于老年代这样的大对象空间,移动对象的代价会相对较高,可能引起较长的暂停时间。
但恰恰我们的CMS是一个低停顿的垃圾回收器,所以选择了标记清除算法,容忍了内存碎片的问题。

什么是Concurrent Mode Failure

  • 浮动垃圾:

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

CMS收集器无法处理浮动垃圾(Floating Garbage),可能出现“Concurrent Mode Failure”失败而导致另一次Full GC的产生。
(1)如果对象提升到年老代的速度太快,而CMS收集器不能保持足够多的可用空间时,就会导致年老代的运行空间不足;
(2)当年老代的碎片化达到某种程度,使得没有足够空间容纳从新生代提升上来的对象时,也会发生并发模式失败。
当发生并发模式失败时,年老代将进行垃圾收集以释放可用空间,同时也会整理压缩以消除碎片,这个操作需要停止所有的java应用线程,并且需要执行相当长时间。

如果发生了Concurrent Mode Failure ,就会垃圾回收器退化,由Serial old来进行垃圾回收,此时产生全局停顿,耗时较高,应避免发生。

四. 吞吐量与停顿时间

JVM的吞吐量是指在一定时间内,JVM能够执行的任务数量。
JVM的停顿时间则是指在执行任务的过程中,JVM需要停止执行任务来进行垃圾回收等操作所花费的时间。
JVM的吞吐量和停顿时间确实是存在一定的互斥关系的。
所以想要其中一个特性就需要舍弃到另外一个特性

影响因素

以下是影响CMS吞吐量和停顿时间的主要因素:
堆大小:较大的堆可以容纳更多的对象,减少垃圾回收的频率,从而提高吞吐量。但是,较大的堆也意味着更长的垃圾回收时间,可能导致较长的停顿时间。
并发线程数:CMS使用并发线程来执行标记和清除阶段。增加并发线程数可以提高并发执行的时间,减少停顿时间。但是,过多的并发线程可能会导致线程竞争和额外的系统开销,可能对吞吐量产生负面影响。
触发垃圾回收的阈值:CMS会根据触发垃圾回收的阈值来决定执行垃圾回收的时机。较低的阈值可能导致频繁的垃圾回收,增加停顿时间;而较高的阈值可能延迟垃圾回收,增加吞吐量但可能导致较长的停顿时间。
并发标记时间:并发标记阶段是CMS的核心,它需要在应用程序运行的同时进行垃圾对象的标记。较长的并发标记时间会增加停顿时间,而较短的并发标记时间会增加吞吐量。因此,并发标记的效率对吞吐量和停顿时间都有影响。
应用程序的行为:应用程序的内存分配模式、对象的生命周期等因素也会影响CMS的性能。如果应用程序产生了大量的垃圾对象或者有过多的存活对象,可能会增加垃圾回收的负担,导致较长的停顿时间。

如何平衡两者

一般来说,为了提高JVM的吞吐量,我们可以采取一些措施,比如增加并发线程数、调整垃圾回收策略等。但这些措施可能会增加JVM的停顿时间,因为在进行并发线程操作和垃圾回收操作时,JVM需要停止执行任务。
相反,为了减少JVM的停顿时间,我们可以采取一些措施,比如选择更加智能的垃圾回收策略、调整垃圾回收频率等。但这些措施可能会降低JVM的吞吐量,因为在进行智能垃圾回收和调整回收频率时,JVM需要占用更多的计算资源,导致无法执行更多的任务。
因此,在实际应用中,我们需要根据具体情况综合考虑吞吐量和停顿时间之间的关系,选择合适的JVM配置和垃圾回收策略。同时,我们也可以采用一些优化技巧,比如使用并发垃圾回收、调整堆大小等,来平衡吞吐量和停顿时间的关系。

五. CMS在停顿时间上做了哪些优化

  1. 与用户线程并发
  2. 采用标记清除算法
  3. 由于最耗费时间的并发标记与并发清除阶段都不需要暂停工作,所以整体的回收是低停顿的

六. 常见的CMS参数

①. -XX:+UseConcMarkSweepGC: 手动指定使用CMS收集器执行内存回收任务
(开启该参数后会自动将一XX: +UseParNewGC打开。即: ParNew (Young区用) +CMS (0ld区用) +Serial 0ld的组合)
②. -XX:CMSlnitiatingOccupanyFraction:设置堆内存使用率的阈值,一旦达到该阈值,便开始进行回收

  • JDK5及以前版本的默认值为68,即当老年代的空间使用率达到68%时,会执行一次CMS 回收。JDK6及以上版本默认值为92%
  • 如果内存增长缓慢,则可以设置一个稍大的值,大的阈值可以有效降低CMS的触发频率,减少老年代回收的次数可以较为明显地改善应用程序性能。反之,如果应用程序内存使用率增长很快,则应该降低这个阈值,以避免频繁触发老年代串行收集器。因此通过该选项便可以有效降低Full GC的执行次数

③. -XX:+UseCMSCompactAtFullCollection:用于指定在执行完Full GC后对内存空间进行压缩整理,以此避免内存碎片的产生。不过由于内存压缩整理过程无法并发执行,所带来的问题就是停顿时间变得更长了
④. -XX:CMSFullGCsBeforeCompaction:设置在执行多少次Full GC后对内存空间进行压缩整理
⑤. -XX:ParallelCMSThreads:设置CMS的线程数量

  • CMS 默认启动的线程数是(Parallel****GCThreads+3)/4
  • ParallelGCThreads 是年轻代并行收集器的线程数。当CPU 资源比较紧张时,受到CMS收集器线程的影响,应用程序的性能在垃圾回收阶段可能会非常糟糕)

七.参考:

java全栈知识体系
javaguide
CMS为什么采用标记-清除算法
CMS低延迟垃圾收集器详解
jvm吞吐量和停顿时间是互斥的

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

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

相关文章

Qt扫盲-QTreeView 理论总结

QTreeView 理论使用总结 一、概述二、快捷键绑定三、提高性能四、简单实例1. 设计与概念2. TreeItem类定义3. TreeItem类的实现4. TreeModel类定义5. TreeModel类实现6. 在模型中设置数据 一、概述 QTreeView实现了 model 中item的树形表示。这个类用于提供标准的层次列表&…

Python3.x安装Pandas教程

python3.x 安装pandas总是会出现一些乱七八糟的问题,那现在就给你们讲述一种超级简单的安装方法,非常简单。 1,检查自己的python版本,我的是python3.4 32位的 2,https://www.lfd.uci.edu/~gohlke/pythonlibs/ 进入此网…

IIS部署Flask

启用 CGI 安装wfastcgi pip install wfastcgi 启用 wfastcgi 首先以管理员身份运行wfastcgi-enable来在IIS上启用wfastcgi,这个命令位于c:\python_dir\scripts,也就是你需要确保此目录在系统的PATH里,或者你需要cd到这个目录后再执行。 #…

np.clip()函数用法

代码: import numpy as npdelta np.clip(1.2, a_min0, a_max1)print(delta) 结果:

防御安全第五次作业

1. 什么是数据认证,有什么作用,有哪些实现的技术手段? 数据认证是指保证数据的真实性、完整性和可信度,以确保数据不被篡改或伪造。其作用包括但不限于: 保护关键数据不被恶意篡改或损坏 提供数据来源的可靠性和安全性…

ToBeWritten之记录狩猎过程

也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 转移发布平台通知:将不再在CSDN博客发布新文章,敬…

nodeJs 图片下载功能实现

const cheerio require("cheerio"); const axios require("axios"); const fs require("fs"); const request require("request"); const path require(path); // 图片存储位置 const fileImgUrl "./images/"; // 获取…

外部中断的基本操作

题目背景 定义一个 Working() 函数,使L1指示灯不断闪烁。将P32引脚定义成外部中断功能,按下S5按键就会产生外部中断触发信号,在中断响应函数中,点亮L8指示灯,延时较长一段时间后熄灭,该功能用两种方法实现…

ToBeWritten之评估数据质量

也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 转移发布平台通知:将不再在CSDN博客发布新文章,敬…

BLIP-2小结

paper:BLIP-2: Bootstrapping Language-Image Pre-training with Frozen Image Encoders and Large Language Models 引用量:376(截止2023-09) motivation BLIPv2主要从模态对齐、高效训练两个方向对图文多模态预训练任务&…

Unity AI Sentis 基础教程

Unity AI Sentis基础教程 Unity AI Sentis基础教程Unity AI 内测资格申请Unity 项目Package Manager开始尝试模型下载识别图片完整代码代码搭载运行 射线绘画 URP(扩展)射线绘画脚本脚本搭载效果 Sentis 是 AI 模型的本地推理引擎,它利用最终…

漏洞扫描与利用

1.通过Kali对服务器场景server2003以半开放式不进行ping的扫描方式并配合a,要求扫描信息输出格式为xml文件格式,从生成扫描结果获取局域网(例如172.16.101.0/24)中存活靶机,以xml格式向指定文件输出信息(使…

轻量级接口自动化测试框架

大致思路: jmeter完成接口脚本,Ant完成脚本执行并收集结果生成报告,最后利用jenkins完成脚本的自动集成运行. 环境安装: 1.jdk1.7 配置环境变量(参考前面的分页) 2.jmeter解压到本地,ant解压到本地 3.Ant解压到本地,并配置环境变量 ANT_HOME:D:\jmeter\apache-ant-1.9.6 P…

学习css 伪类:has

学习抖音: 渡一前端提薪课 首先我们看下:has(selector)是什么 匹配包含(相对于 selector 的 :scope)指定选择器的元素。可以认为 selector 的前面有一个看不见的 :scope 伪类。它的强大之处是,可以实现父选择器和前面兄弟选择器…

2023年最新问卷调查工具排行榜:揭秘实力榜单

问卷调查是从目标受众那里收集有价值的反馈和见解的有效方式。正确的调查问卷工具可以使问卷的创建、分发和分析变得更加容易和高效。在本文中,我们将问卷调查工具排行榜实力榜,为大家选择问卷平台的时候提供有价值的参考意见。 1、Zoho Survey Zoho S…

三分钟阿里云服务器全方位介绍(看一篇就够了)

阿里云服务器ECS英文全程Elastic Compute Service,云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务,阿里云提供多种云服务器ECS实例规格,如经济型e实例、通用算力型u1、ECS计算型c7、通用型g7、GPU实例等,阿里云百科aliyunbai…

经典文献阅读之--MapTR(环视车道线地图提取)

0. 简介 最近环视图像处理其实已经非常火了,最近地平线&华科则是提出了一种新的环视车道线地图提取工具。高清(HD)地图提供了驾驶场景丰富而精确的环境信息,是自动驾驶系统规划中基础且不可或缺的组成部分。《MapTR: Structu…

“益路同行”栏目专访 第06期—小星星关爱联盟创始人魏洁荣老师

中国善网在本届(第十届)慈展会上特别推出了《益路同行》采访栏目,《益路同行》栏目旨在寻觅公益之路上同行者的故事,挖掘公益更深层次的内涵,探索新时代公益发展道路。希望公益企业、人物、故事被更多人看到&#xff0…

软件测试/测试开发丨App自动化测试-弹窗异常处理

点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接:https://ceshiren.com/t/topic/27692 黑名单处理 运行过程中不定时弹框(广告弹窗,升级提示框,新消息提示框等等) 弹框不是 BUG&#xff0…

2023/9/28 -- ARM

【内存读写指令】 int *p0X12345678 *p100;//向内存中写入数据 int a *p;//从内存读取 1.单寄存器内存读写指令 1.1 指令码以及功能 向内存中写: str:向内存中写一个字(4字节)的数据 strh:向内存写半个字(2字节)的数据 strb:向内存写一个字…