千家信息网

垃圾回收CMS的过程是怎样的

发表于:2025-01-21 作者:千家信息网编辑
千家信息网最后更新 2025年01月21日,本篇内容主要讲解"垃圾回收CMS的过程是怎样的",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"垃圾回收CMS的过程是怎样的"吧!一、CMS介绍全称 Conc
千家信息网最后更新 2025年01月21日垃圾回收CMS的过程是怎样的

本篇内容主要讲解"垃圾回收CMS的过程是怎样的",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"垃圾回收CMS的过程是怎样的"吧!

一、CMS介绍

全称 Concurrent Mark Sweep,是一款并发的、使用标记-清除算法的垃圾回收器。

1、并行,STW时间短暂。
2、没有压缩和整理,产生内存碎片。

对象在标记过程中,根据标记情况,分成三类:

1、白色对象,表示自身未被标记;
2、灰色对象,表示自身被标记,但内部引用未被处理;
3、黑色对象,表示自身被标记,内部引用都被处理;

触发时间:如果添加了一下参数

当老年代的使用率达到80%时,就会触发一次cms gc。

二、CMS的收集过程分为6个步骤。

假设CMS GC之前的堆结构如下图:

1、初始标记(InitialMarking)

这是一个STW过程,主要分两步
1、标记GC Roots可达的老年代对象;
2、遍历GC Roots下的新生代对象能够可达的老年代对象;
3、此过程不对以上可达的老年代对象进行进一步的可达扫描。

结果:

2、并发标记(Marking)

该阶段GC线程和应用线程并发执行,遍历InitialMarking阶段标记出来的存活对象,然后继续递归标记这些对象可达的对象。
这个过程应用线程在运行,可能Young GC也会发生,会发生以下的情况:
1、新生代对象晋升到老年代
2、在老年代分配对象
3、新老年代对象的引用发生变化。

结果:

2.1、那么如何处理并发标记过程中对象的变化呢?

CMS使用上一节讲过的Card Table来解决这个问题
并发标记过程中引用发生变化的对象所在的Card,在Card Table来记录为"脏卡",这样在后面重新标记的时候会把这些对象也当做GC Root来遍历

但是Young GC如果发生,比方说:
1、并发标记还未扫描到脏卡1.
2、Young GC扫描完脏卡,并改变dirty到clean.
3、并发标记扫描,发现卡1已不是脏卡,则不会处理,这就造成了漏标。

2.2、如果解决以上的问题呢?

CMS中,有另一种数据结构(Mod Union Table)
Mod Union Table是一个位向量,每个单元的大小只有1位,每个单元对应一个Card(Card的大小是512字节,Card Table每一个单元的大小是1个字节)
在新生代GC处理dirty card之前,先把该card在Mod Union Table里面的对应项置位。
这样,CMS在执行重新标记阶段的时候,就会扫描Mod Union Table和card table里面被标记的项。

3、预清理(Precleaning&AbortablePreclean)

3.1 Precleaning

通过参数CMSPrecleaningEnabled选择关闭该阶段,默认启用,主要做两件事情:

1、处理新生代已经发现的引用,比如在并发阶段,在Eden区中分配了一个A对象,A对象引用了一个老年代对象B(这个B之前没有被标记),在这个阶段就会标记对象B为活跃对象。
2、在并发标记阶段,如果老年代中有对象内部引用发生变化,会把所在的Card标记为Dirty(包括ModUnionTalble),通过扫描这些Table,重新标记那些在并发标记阶段引用被更新的对象。

3.2、AbortablePreclean

该阶段发生的前提是,新生代Eden区的内存使用量大于参数CMSScheduleRemarkEdenSizeThreshold 默认是2M,如果新生代的对象太少,就没有必要执行该阶段,直接执行重新标记阶段。

为什么需要这个阶段,存在的价值是什么?

因为CMS GC的终极目标是降低垃圾回收时的暂停时间,所以在该阶段要尽最大的努力去处理那些在并发阶段被应用线程更新的老年代对象,这样在暂停的重新标记阶段就可以少处理一些,暂停时间也会相应的降低。

在该阶段,主要循环的做两件事:

1、处理 From 和 To 区的对象,标记可达的老年代对象
2、和上一个阶段一样,扫描处理Dirty Card和ModUnionTalble中的对象。

当然了,这个逻辑不会一直循环下去,打断这个循环的条件有三个:

1、可以设置最多循环的次数 CMSMaxAbortablePrecleanLoops,默认是0,意思没有循环次数的限制。
2、如果执行这个逻辑的时间达到了阈值CMSMaxAbortablePrecleanTime,默认是5s,会退出循环。
3、如果新生代Eden区的内存使用率达到了阈值CMSScheduleRemarkEdenPenetration,默认50%,会退出循环。

4、重新标记(STW的过程)

在之前的并行阶段,可能产生新的引用关系如下:

1、老年代的新对象被GC Roots引用
2、老年代的未标记对象被新生代对象引用
3、老年代已标记的对象增加新引用指向老年代其它对象
4、新生代对象指向老年代引用被删除

上述对象中可能有一些已经在Precleaning阶段和AbortablePreclean阶段被处理过,但总存在没来得及处理的,所以需要做以下事情:

1、遍历新生代对象,重新标记
2、根据GC Roots,重新标记
3、遍历老年代的Dirty Card和Mod Union Table,重新标记

在第1步骤中,需要遍历新生代的全部对象,如果新生代的使用率很高,需要遍历处理的对象也很多,这对于这个阶段的总耗时来说,是个灾难(因为可能大量的对象是暂时存活的,而且这些对象也可能引用大量的老年代对象,造成很多应该回收的老年代对象而没有被回收,遍历递归的次数也增加不少),如果在这之前发生一次YGC,这样就可以避免扫描无效的对象。

CMS算法中提供了一个参数:CMSScavengeBeforeRemark,默认并没有开启,如果开启该参数,在执行该阶段之前,会强制触发一次YGC,可以减少新生代对象的遍历时间,回收的也更彻底一点。

5、并发清理

清理在标记阶段收集标识为不可达的对象

6、重置

清除数据结构,准备下一次并发收集。

到此,相信大家对"垃圾回收CMS的过程是怎样的"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

对象 标记 阶段 年代 新生 新生代 处理 过程 循环 时间 垃圾 参数 线程 变化 使用率 内存 单元 大小 次数 结构 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 软件开发英文面试题 网络安全的目标与意义 服务器代理公司需要什么资质 涉密网络安全责任制实施方案 庐阳区一站式网络技术开发价位 数据库技术及应用项目式教程 软件开发公司公关策划书 qq登录失败 服务器连接中 离线式数据库 固化专业知识的数据库 wex5 使用本地数据库 永川区网络软件开发服务代理商 盲盒商城app软件开发 徐州通用软件开发价格优惠 魔兽世界多少人的服务器不用排队 数据库memo类型 黑龙江省诚亚网络技术公司 织雾武僧幻化数据库 传奇服务器增加命中设置 意识形态网络安全讲座主持词 马萨诸塞州的摩西网络安全公司 服务器电源都有哪些 服务器联机解说视频教程 部队网络安全ppt 网络边界防护集群服务器 封面模板软件开发 哪种数据库安全性比较高 浙江企业软件开发要多少钱 管理软件开发的目的 南京学习软件开发公司哪家好
0