【JVM精通之路】垃圾回收-三色标记算法

首先预期你已经基本了解垃圾回收的相关知识,包括新生代垃圾回收器,老年代垃圾回收器,以及他们的算法,可达性分析等等。


先想象一个场景

最开始黑色节点是GC-Roots的根节点,这些对象有这样的特点因此被选为垃圾回收的根节点。

虚拟机栈(栈桢中的本地变量表)中的引用的对象 
方法区中的类静态属性引用的对象 
方法区中的常量引用的对象 
本地方法栈中JNI的引用的对象

记不住没事~你只需要知道,这些对象都有长生不老的特点,它一直存在,所以从它开始遍历查找,才知道哪些对象没有人使用,可以被回收。

那么最开始堆里的对象默认都是白色的。

现在要开始垃圾回收了。

如果是你你怎么设计,嗯,我们因为有这张图从三维看二维开天眼立马知道哪些对象是活着的。

但是程序不知道,它需要遍历。这里需要注意一个其他博客都没有提到的点,这里是GC-Roots引用了右边的对象,而不是右边的对象引用了GC-Roots。

你可以这么思考,因为是Roots依赖了右边的某些对象,又因为Roots是持久存在的,那么右边某些对象也必须存在。所以是Roots引用了某些对象,所以这些对象必须存活。很多博客在这里没有说清楚引用关系。

如果是右边对象依赖了GC-Roots,那么右边的对象存在与否和Roots有什么关系?

因为人引用了空气,他需要空气,所以必须空气存在。

1.定义

黑色:一直存在不需要清理的对象,它用到的对象都确定需要存活。下一次不扫描黑色对象。

灰色:一直存在不需要清理的对象,它用到的其他对象还没确定是否存活。下一次从它开始扫描。

白色:扫描完毕后,还是白色的对象,就清理掉。

颜色的标记 记录在每个对象的头部信息的Markword中!

CMS有四步,初始标记(STW),并发标记,重复标记(STW),并发清除四步。

1.开始遍历

第一次遍历:

第二次遍历:

 第三次扫描:

 第四次扫描:

 第五次扫描:

 第六次扫描

 

 第七次扫描:

 然后这时候把所有白色对象清理掉。

以上的图的过程都是发生在并发标记中。先不考虑重复标记。

2.思考

2.1 三色标记解决了什么问题

思考一下,你现在幻身为一个线程,你只知道堆里有一堆对象,你并不知道他们是什么颜色,你现在只知道根节点在堆内存的哪个地址下。老板叫你去清理堆内存的废物对象。而且你随时可能会被CPU抽掉灵魂。(线程被阻塞)

你:我特么不能每次醒过来都从根节点去遍历吧。不行我得有个记事本,(线程可以访问标记记录集合)记住哪些我标记了的。这样下次直接从已经标记的对象开始遍历。

那这时候只需要黑白二色标记就够了。

但是有几个问题:

1.黑色太多了。我需要从很多黑色对象开始找,费时,麻烦!

2.我在把对象18由白色变黑的过程中,如果对象7对象18抛弃了。那我是不是多标了。让本来应该死亡清除的对象18没有被清除。

3.现在堆内存中全都黑了,我要清理垃圾了。正要清理的时候,对象7突然引用了对象17,这时候就会出现漏标的问题。

如何解决呢?

思考...


问题1,那么能不能有个中间态。把还需要往下扫描的对象变成灰色,把不需要继续往下扫描的对象变成黑色。这时候往回看上文的扫描图,可以看见灰色节点的集合是非常少的,因此每次我只需要从较少的节点开始扫描

好了我手里有两个笔记本了。一个灰色笔记本,一个黑色笔记本。

解决了扫描对象过多的问题的同时也能解决STW的时间。

重新想起CMS有四步过程,初始标记(STW),并发标记,重复标记(STW),并发清除四步。

因为重新标记阶段也只需要从灰色节点开始扫描了。因为黑色是确定是活的,就算重新标记之后死掉了,也最多变成浮动垃圾,因为重新标记阶段是STW的,所以也不会有引用的变化。

并且只有并发标记的过程才会有引用的变化。


问题2,本来应该清除的对象没有被清除,这问题不大,当成浮动垃圾下一次垃圾回收再扫描一次就行了。多标本质造成浮动垃圾的问题。问题不大。

问题3,漏标怎么办,不能错杀啊。没有被标记的对象是要被杀掉的。不能被错杀。那么我必须stop the world了!STW。

只有停止所有用户线程才能避免我在标记对象的过程中,有对象复活了但是没被我标记,被活埋了!这个很重要。并不是因为三色标记才能避免漏标问题。三色标记只是为了减少STW的时间,以及减少遍历树的时间。

很多博客这里压根没讲清楚因果关系。只告诉你三色标记和标记清除算法里,有初始标记,并发标记,重复标记,怎么变色,多标,漏标问题。但是没把问题和解决方案对应起来。

我们都知道CMS有四步,初始标记(STW),并发标记,重复标记(STW),并发清除四步。

我不能从GC-Roots开始遍历的时候就STW一直到并发清除吧。STW这么长那么CMS的意义就不存在了。那么考虑哪些步骤可以与用户线程并发执行。

初始标记:将直接与GC-Roots的对象变灰,这部分速度很快,且不能出错,可以STW,性价比高。

并发标记:需要将对所有灰色节点遍历树结构,比较耗时,这部分肯定不能STW。

重复标记:这部分是最后扫尾工作,肯定不能让用户线程来参一脚,必须STW。并且修复并发标记时的错误标记,把并发标记漏标的白色变灰。

这里很多博客也没说清楚是什么错误。那么我们研究一下:并发标记只会让白变灰,或让灰变黑。

因为到重复标记时,堆内存只有黑白色了。

那么修复错误:

让白变灰:因为并发标记没有遍历到的对象一直白色,并发标记到重复标记开始之前如果有黑色对象引用到了白色对象。那么重复标记需要将白变灰。同时它是STW,这时变灰正好解决漏标。

为什么没有让黑变灰:正常来说并发标记标记为黑色后,但是之后黑色对象如果没有被任何对象引用了。需要将它变灰。但是重复标记只是扫尾工作,它是STW的,并且需要解决漏标问题。如果此时又让黑变灰,那么是否又考虑让灰变白。但是这两步完全可以放到下一轮垃圾回收的并发标记中去做,因为并发标记不STW,同时也能扫描到灰色对象。这里也是CMS单次回收不能很好解决浮动垃圾的问题,他可以解决,但是没必要。

之后并发清除可以清除白色对象了。

总结:

也就是三色标记法,可以区分标记的过程中的粒度,从而让垃圾回收器根据不同的标记阶段,更好的做出不一样的行为,并且对不同的行为采用不一样的STW规则,从而减少STW时间,增加用户线程运行时间。黑色就是需要活着的对象,灰色就是还需要往下遍历的对象,白色就是需要清除的对象。三个颜色也是标明了对象处于的扫描阶段。

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

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

相关文章

Transformers x SwanLab:可视化NLP模型训练

HuggingFace 的 Transformers 是目前最流行的深度学习训框架之一(100k Star),现在主流的大语言模型(LLaMa系列、Qwen系列、ChatGLM系列等)、自然语言处理模型(Bert系列)等,都在使用T…

Mowgli用于配对多组学整合

对同一组细胞的多个分子层进行分析逐渐流行。越来越需要能够联合分析这些数据的多视图学习方法。Mowgli是一种支持配对多组学数据的整合方法。值得注意的是,Mowgli将非负矩阵分解和最优传输相结合,同时提高了非负矩阵分解的聚类性能和可解释性。作者将Mo…

android studion 一直编译失败

无外网,无法下载对应的库导致编译失败 配置代理 1.修改镜像源 资源路径 为国内镜像 如下为国美腾讯软件镜像 distributionUrlhttps\://mirrors.cloud.tencent.com/gradle/gradle-8.6-bin.zip 2.构建仓储失败 无法下载。 添加国内仓储如下位置,重新…

SAP MM模块后台配置(下)

3.10 采购订单的审批过程 配置路径 IMG->物料管理-采购-采购订单-审批过程-含分类的过程 事务代码 SPRO 配置请求号 配置描述:我们用这个配置来进行九牧集团用到的采购订单的审批策略的定义: 配置屏幕: …

Jmeter元件及基本作用域

🚀从今天开始学习性能测试工具——Jmeter,小梦也是先学习了下Jmeter的元件概念以及其基本的作用域,整理了下笔记,希望不管是从事开发领域还是测试领域的朋友们,我们一起学习下Jmeter工具,提升工作中的技能&…

【软考】下篇 第12章 信息系统架构设计理论与实践

目录 一、信息系统架构的定义二、信息系统架构风格三、信息系统架构分类四、信息系统常用的4种架构模型(SCSB)五、企业信息系统的总体框架ISA六、TOGAF & ADM七、信息化总体架构方法信息化六要素信息化架构模式信息系统生命周期(规分设实…

7个靠谱的副业赚钱方法,宝妈,上班族,学生党可以做的兼职副业

你是否也曾面临过这样的困境:生活费紧张,想要找份兼职来补贴家用或是满足自己的小心愿?别担心,今天我将带领你踏入这个丰富多彩的兼职世界,助你轻松达成月入过千的小目标! 在我漫长的兼职探索旅程中&#…

【区域脑图论文笔记】BrainNetCNN:第一个专门为脑网络连接体数据设计的深度学习框架

【区域脑图论文笔记】BrainNetCNN:第一个专门为脑网络连接体数据设计的深度学习框架 信息概览与提炼采用的数据与结果数据集结果概览一眼 重点图与方法概览核心与优劣总结模型与实验论文方法E2E的理解E2N的理解N2G的理解三个卷积层设计的理解 论文实验与讨论 总结与…

力扣232. 用栈实现队列(两栈实现队列)

Problem: 232. 用栈实现队列 文章目录 题目描述思路Code 题目描述 思路 利用两个栈,一个入栈一个出栈搭配着实现队列的相关操作: 1.创建两个栈stack1和stack2; 2.void push(int x):将要入队的元素先入栈stack1; 3.int pop()&…

倒计时 1 天!「飞天技术沙龙-CentOS 迁移替换专场」演讲亮点一览

各位开发者们: 「飞天技术沙龙 - CentOS 迁移替换专场」即将于本周三在北京召开!昨天,小龙为参会者公布了详细参会指南,今天带大家了解各演讲内容亮点。 活动时间:5 月 29 日(本周三) 13:30-17…

pod容器基础概念

一 Pod基础概念: ①Pod是kubernetes中最小的资源管理组件,Pod也是最小化运行容器化应用的资源对象。一个 Pod代表着集群中运行的一个进程。一个pod包含一个或多个容器。如:应用容器/业务容器(淘 宝、京东、拼多多后台&#xff…

水电自动抄表系统是什么?

1.简述:水电自动抄表系统 水电自动抄表系统是一种现代化计量检定解决方法,为提升公用事业服务项目的效率和精确性。传统式手动抄水表方法已经被这类高效率、精准的自动化系统所替代,它能够实时、远程控制地收集解决水电使用数据。 2.系统原…

国产性能怪兽——香橙派AI Pro(8T)上手体验报告以及性能评测

目录 1、引言2、性能参数3、开箱体验4、实际使用5、性能比较总结参考文章 1、引言 第一次接触香橙派的开发板,之前使用过Arduino、树莓派3B、树莓派4B,STM32,51单片机,没有想到国产品牌性能一样强劲,使用起来也是很方便…

Llama 3 模型家族构建安全可信赖企业级AI应用之使用 Llama Guard 保护大模型对话 (八)

LlaMA 3 系列博客 基于 LlaMA 3 LangGraph 在windows本地部署大模型 (一) 基于 LlaMA 3 LangGraph 在windows本地部署大模型 (二) 基于 LlaMA 3 LangGraph 在windows本地部署大模型 (三) 基于 LlaMA…

鸿蒙开发接口图形图像:【@ohos.screen (屏幕)】

屏幕 本模块提供管理屏幕的一些基础能力,包括获取屏幕对象,监听屏幕变化,创建和销毁虚拟屏幕等。 说明:开发前请熟悉鸿蒙开发指导文档:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。…

LBank研究院: DePIN赛道解析|加密精神与Jevons悖论的第三世界

作者:Eva,LBank研究员 *本人谨代表作者观点,不构成任何交易建议。 *本文内容为原创,版权为LBank所有,如需转载请注明作者和出处,否则将追究法律责任。 TLDR: DePIN是对传统老牌硬件的洗牌挑战&#xff…

节水“云”科普丨北京昌平VR节水云展馆精彩上线

2024年5月15日上午,由北京昌平区水务局主办的“推进城市节水,建设美丽昌平——2024年全国城市节约用水宣传周暨‘坚持节水优先 树立节水标杆’昌平节水在行动主题实践活动”隆重举办,活动期间,昌平区水务局应用VR虚拟现实技术创新…

你什么时候感觉学明白Java了?

学是学不明白Java的,要学明白Java,一定只能在工作以后。 1 在学习阶段,哪怕是借鉴别人的学习路线,其实依然会学很多不必要的技能,比如jsp,swing,或者多线程,或者设计模式。 2 或者…

php 变量值传递和引用传递

一、值传递和引用传递 二、在foreach 中的引用传递 public function actionR(){$a [a>1,b>2,];foreach ($a as &$item){$i 100;$item $i;}$b [a>1,b>2];foreach ($b as &$item){$i 99;$item $i;}var_dump($a,$b);}可见 在两个foreach 中&$item …

md5强弱碰撞

一,类型。 1.弱比较 php中的""和""在进行比较时,数字和字符串比较或者涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行。按照此理,我们可以上传md5编码后是0e的字符串,在…