当前位置:网站首页>CMS 执行的七个阶段
CMS 执行的七个阶段
2022-06-27 16:55:00 【用户3147702】
1. 引言
java 优于 c++ 的一个亮点就是自动的垃圾回收机制,成也萧何败萧何,最困扰 java 程序员的问题往往又都和垃圾回收机制有关,作为一个 java 程序员,如果你不了解 java 垃圾回收的机制,那么你时刻都可能面临性能的瓶颈,甚至遇到种种诡异的问题而无从下手。
此前,我们已经介绍过 java 垃圾回收相关的很多内容:
本文我们就来详细介绍一个 java 中明星级的垃圾回收器 CMS 的回收机制,而新一代的 G1 回收器的执行机制会在下一篇文章中再来介绍,敬请期待。
2. CMS 垃圾收集器概览
CMS 是 Concurrent Mark Sweep 的缩写,是现在主流十分常用的老年代垃圾回收器,他的主要目标是用最短的回收停顿时间实现老年代的清理,因此,对于强调用户体验的互联网应用来说,CMS 成为了一个首选。
那么,CMS 垃圾回收器究竟是怎么工作的呢?
CMS 垃圾回收器采用了标记清除算法来实现。
3. 三色标记法
说到“标记-清除”算法,顾名思义,jvm 将整个收集过程划分为了“标记”与“清除”两大步骤来实现。
具体到标记流程,jvm 采用了“三色标记法”,就是将不同的对象划分为三大类:
- 黑色对象 -- 已标记,内部引用已经都被处理
- 白色对象 -- 未被标记对象
- 灰色对象 -- 已被标记,但内部引用未被处理
我们知道,jvm 是通过可达性分析法来实现标记过程的,jvm 从 GC Root 开始,逐步遍历引用树来实现对内存区域内每个对象的标记,可以参看:
java 对象存活判定算法
4. CMS 的执行步骤
一般来说,人们通常把 CMS 的执行过程分为四个步骤:
- 初始标记
- 并发标记
- 重新标记
- 并发清除
加上可选的阶段,CMS 回收的过程可以划分为七个步骤,下面我们就来详细介绍:
- 初始标记
- 并发标记
- 并发预清理
- 可中断的并发预清理
- 重新标记
- 并发清除
- 并发重置
4.1 初始标记
如上所述,初始标记最重要的工作就是以 GC-Roots 为起点进行可达性分析,标记出所有当前活跃的也就是被引用的对象。
但是,除了被 GC-Root 引用外,老年代中的对象如果仅被年轻代中的对象引用,他也是不能回收的,因此,在上述以 GC-Roots 为起点进行的标记完成后,还需要遍历新生代对象,标记可达的老年代对象。
由于上述两个过程仅仅遍历被 GC-Roots 和新生代对象直接引用的老年代对象,执行起来速度会非常快,为了避免在标记过程中对象引用的动态变化,在初始标记阶段,程序需要进行短暂停止,这称为“Stop The World”。
jdk8 以后,初始标记支持多线程标记,可以通过 CMSParallelInitialMarkEnabled 参数开启。
4.2 并发标记
“并发标记”阶段所谓的“并发”,指的就是用户线程可以与回收线程同步执行,而不需要让用户线程暂停,从而保证了用户线程的执行效率。
初始标记的过程中,为了尽量缩短用户线程的暂停时间,所以仅对被 GC-Roots 和新生代对象直接引用的老年代对象进行了标记,所以,接下来的一项工作就是对 GC-Roots 和新生代对象间接引用的老年代对象进行标记,这就是并发标记阶段的主要工作了。
4.2.1 如何处理并发标记阶段的引用关系变更
由于在并发标记阶段,用户线程与回收线程并发执行,随时可能有新生代的对象晋升到老年代、直接在老年代分配对象或者引用关系发生变更等等情况发生,这些情况下,jvm 是否必须扫描整个老年代才能够识别出这些发生了变化的对象呢?
答案当然是否定的,HotSpot 使用了一套名叫“卡表”(Card Table)的数据结构来管理老年代的内存,Card Table 实际上就是一个索引列表,每一个表项占用 1 byte 空间,索引内存中占 512 byte 的页空间。
而在对每一个对象引用进行写操作之前和之后 HotSpot 都附加了一定的逻辑,称之为“写屏障”(Write Barrier),写屏障会在一个对象的引用发生变化时,将该对象所在的页在卡表中对应的表项标记为 dirty。
但是,由于 jvm 中对象引用变更是极为频繁的,反复读写卡页显然会有很大的性能开销,于是,从 JDK7 开始,HotSpot 引入了一个新的 JVM 参数 -XX:+UseCondCardMark,从而让已经标记过的卡页不再重复标记。
4.3 并发预清理
这一步是可选的,可以通过参数 CMSPrecleaningEnabled 参数可以启用或关闭该阶段,默认是开启的。
上文已经介绍到,在并发标记阶段,由于引用的变更,可能会产生一些 dirty page,这一阶段的主要工作就就是处理这些脏页,虽然在后面的重新标记阶段也拥有处理脏页的逻辑,但重新标记阶段会 Stop The World,所以这一阶段的核心仍然是让停顿时间尽量缩短。
4.4 可中断的并发预清理
这一阶段的主要工作是处理新生代指向老年代的新引用,从而让老年代的一些未被标记的对象成为活跃对象。
同样,在重新标记阶段也会处理这样的情况,这一阶段仍然是为了缩短停顿时间而进行的。
CMS 对于该阶段有以下 4 个参数:
- CMSScheduleRemarkEdenSizeThreshold -- 当 eden 区空间超过该值时才执行该阶段,默认为 2M
- CMSScheduleRemarkEdenPenetration -- 当 eden 空间使用率大于该值时,中断该阶段的执行,默认为 50%
- CMSMaxAbortablePrecleanTime -- 该阶段的最长执行时间,默认为 5s
- CMSScavengeBeforeRemark -- 强制在该阶段进行一次 minorGC
显然,在这一阶段中要识别新生代对象对老年代对象的新引用,那么就必须扫描整个新生代,这显然是一项很耗时的操作,但由于新生代的对象大多是朝生夕死的,所以如果在一次 minorGC 之后紧接着进行一次预清理,新生代中需要扫描的对象就会所剩无几了。
CMS 通过 CMSScavengeBeforeRemark 参数强制在可中断的并发预清理阶段执行一次 minorGC,虽然 minorGC 也会让用户线程短暂停顿,但这样可以缩短下一阶段的停顿时间,整体上还是利大于弊的。
4.5 重新标记
在上述的并发过程中,用户线程始终在执行,因此随时可能会产生引用变更,比如:
- 老年代未标记对象被新生代对象引用
- 新生代对象晋升到老年代
- 已标记对象增加了对未标记对象的引用
- 已标记对象的引用被删除
这些情况下,很有可能造成标记数据的不准确,如果直接进行清理,就有可能有误清理的情况发生,因此,jvm 需要再一次 Stop The World 来进行重新标记,从而保证在真正的清理前,标记的准确性。
重新标记阶段,jvm 主要进行以下三个工作:
- 遍历新生代对象,重新标记被引用的老年代对象
- 从 GC Roots 出发,重新标记被引用的老年代对象
- 遍历卡表,对脏页内的老年代对象进行重新标记
但由于有了前面三个步骤的反复标记过程,重新标记阶段的工作量已经被大大降低,停顿时间当然也因此大大减少。
4.6 并发清除
完成了标记工作,就只剩下最后的一步工作,那就是清除了。
由于被清除的对象都是未被使用的对象,因此在清楚操作进行中,是不需要 Stop The World 的,这一步操作也是和用户线程同步执行的。
4.7 并发重置
完成了整个 CMS 的标记-清除工作后,需要将 CMS 算法的内部数据进行重置,从而让下一次 GC 顺利开始。
5. 示例:GC 日志
下面是一次 CMS 进行 Full GC 的完整日志,我们可以清楚的看到每一阶段的运行信息与耗时情况:
2021-01-17T12:52:41.268+0800: 463.575: Total time for which application threads were stopped: 0.4222317 seconds, Stopping threads took: 0.0001890 seconds2021-01-17T12:52:41.268+0800: 463.575: Application time: 0.0000643 seconds // 初始标记(Initial Mark)2021-01-17T12:52:41.271+0800: 463.578: [GC (CMS Initial Mark) [1 CMS-initial-mark: 1777676K(3145728K)] 1987618K(5033216K), 0.0327958 secs] [Times: user=0.12 sys=0.00, real=0.04 secs] // 并发标记(Concurrent Mark)2021-01-17T12:52:41.304+0800: 463.611: [CMS-concurrent-mark-start]2021-01-17T12:52:42.050+0800: 464.356: [CMS-concurrent-mark: 0.746/0.746 secs] [Times: user=2.61 sys=0.21, real=0.74 secs] // 并发预清理(Concurrent Preclean)2021-01-17T12:52:42.050+0800: 464.356: [CMS-concurrent-preclean-start]2021-01-17T12:52:42.171+0800: 464.477: [CMS-concurrent-preclean: 0.056/0.121 secs] [Times: user=0.47 sys=0.05, real=0.12 secs] // 并发可取消的预清理(Concurrent Abortable Preclean)2021-01-17T12:52:42.171+0800: 464.477: [CMS-concurrent-abortable-preclean-start]2021-01-17T12:52:43.753+0800: 466.059: [CMS-concurrent-abortable-preclean: 1.128/1.582 secs] [Times: user=4.86 sys=0.41, real=1.59 secs] // 最终标记(Final Remark)2021-01-17T12:52:43.756+0800: 466.063: [GC (CMS Final Remark) [YG occupancy: 1414648 K (1887488 K)]466.063: [Rescan (parallel) , 0.2583497 secs]466.321:[weak refs processing, 0.0005512 secs]466.322: [class unloading, 0.0514608 secs]466.373: [scrub symbol table, 0.0122328 secs]466.385: [scrub string table, 0.0017416 secs][1 CMS-remark: 1974197K(3145728K)] 3388846K(5033216K), 0.3265593 secs] [Times: user=0.83 sys=0.00, real=0.33 secs] // 并发清除(Concurrent Sweep)2021-01-17T12:52:44.083+0800: 466.389: [CMS-concurrent-sweep-start]2021-01-17T12:52:48.578+0800: 470.885: [CMS-concurrent-sweep: 3.224/4.495 secs] [Times: user=14.43 sys=1.19, real=4.49 secs] // 并发重置(Concurrent Reset)2021-01-17T12:52:48.638+0800: 470.945: [CMS-concurrent-reset-start]2021-01-17T12:52:48.647+0800: 470.953: [CMS-concurrent-reset: 0.008/0.008 secs] [Times: user=0.06 sys=0.01, real=0.01 secs]
边栏推荐
- 【网络研讨会】MongoDB 携手 Google Cloud 加速企业数字化创新
- The data synchronization tool dataX has officially supported reading and writing tdengine
- Three methods to quickly open CMD in a specified folder or place
- [cloud based co creation] the "solution" of Digital Travel construction in Colleges and Universities
- 一位平凡毕业生的大学四年
- MongoDB和MySQL的区别
- How to use the low code platform of the Internet of things for picture management?
- 利用OpenCV执行相机校准
- New Zhongda chongci scientific and Technological Innovation Board: annual revenue of 284million and proposed fund-raising of 557million
- Hikvision tools manager Hikvision tools collection (including sadp, video capacity calculation and other tools) a practical tool for millions of security practitioners
猜你喜欢

SQL update批量更新

MFS分布式文件系统
![[notice of the Association] notice on holding summer special teacher training in the field of artificial intelligence and Internet of things](/img/ef/5b86170e60a7e03c4db512445540b9.jpg)
[notice of the Association] notice on holding summer special teacher training in the field of artificial intelligence and Internet of things

在arcgis中以txt格式导出点的坐标

Hikvision tools manager Hikvision tools collection (including sadp, video capacity calculation and other tools) a practical tool for millions of security practitioners

国际数字经济学院、华南理工 | Unified BERT for Few-shot Natural Language Understanding(用于小样本自然语言理解的统一BERT)

工作流自动化 低代码是关键

产学合作协同育人,麒麟软件携手南开大学合力完成《软件测试与维护》实践课程

MySQL中的行转列和列转行

Vscode suggests that you enable gopls. What exactly is it?
随机推荐
TIA博途_基于SCL语言制作模拟量输入输出全局库的具体方法
Daily leetcode force deduction (31~35)
银河麒麟V10系统激活
Minmei new energy rushes to Shenzhen Stock Exchange: the annual accounts receivable exceeds 600million and the proposed fund-raising is 450million
InfluxDB集群功能不再开源,TDengine集群功能更胜一筹
Vscode suggests that you enable gopls. What exactly is it?
MySQL数据库登录和退出的两种方式
Core dynamic Lianke rushes to the scientific innovation board: with an annual revenue of 170million yuan, Beifang Electronics Institute and Zhongcheng venture capital are shareholders
你知道 log4j2 各项配置的全部含义吗?带你了解 log4j2 的全部组件
maxwell 报错(连接为mysql 8.x)解决方法
Market status and development prospect forecast of global active quality control air sampler industry in 2022
阅文、中文在线等网文平台如何布局数字藏品?未来是否会推出“Read/Write-to-Earn”产品?
Contest3182 - the 39th individual training match for 2021 freshmen_ C: [string] ISBN number
International School of Digital Economics, South China Institute of technology 𞓜 unified Bert for few shot natural language understanding
在arcgis中以txt格式导出点的坐标
R language statistics a program running time function system time
Space calculation of information and innovation industry in 2022
Push NFT out of the regulatory dilemma, and BSN launched NFT supporting infrastructure network
Galaxy Kirin V10 system activation
数据同步工具 DataX 已经正式支持读写 TDengine