jvm垃圾收集器-三色标记算法

1.对象已死吗?

在堆里面存放着Java世界中几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还“存活”着,哪些已经“死去”(即不可能再被任何途径使用的对象).

引计数法

引用计数算法是一种垃圾回收算法,它通过记录每个对象被引用的次数来判断对象是否已经成为垃圾并进行回收。当对象被创建时,其引用计数器初始化为0,当有其他对象引用该对象时,其引用计数器就会加1,当引用该对象的对象被销毁时,其引用计数器就会减1。当一个对象的引用计数器变为0时,即表示该对象已经没有被任何其他对象引用,可以被认为是垃圾对象,并被回收。

可达性分析

这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连(用图论的话来说,就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。

在Java语言中,可作为GC Roots的对象包括下面几种:

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象。
  • 方法区中类静态属性引用的对象。
  • 方法区中常量引用的对象。
  • 本地方法栈中JNI(即一般说的Native方法)引用的对象。
2.引用的分类

在JDK 1.2之后,Java对引用的概念进行了扩充,将引用分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4种,这4种引用强度依次逐渐减弱。

  • 强引用就是指在程序代码之中普遍存在的,类似“Object obj = new Object()”这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。
  • 软引用是用来描述一些还有用但并非必需的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常。在JDK 1.2之后,提供了SoftReference类来实现软引用。
  • 弱引用也是用来描述非必需对象的,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。在JDK 1.2之后,提供了WeakReference类来实现弱引用。
  • 虚引用也称为幽灵引用或者幻影引用,它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。在JDK 1.2之后,提供了PhantomReference类来实现虚引用。
3.三色标记算法
3.1三色标记标记流程

我们知道CMS垃圾回收器是通过可达性分析找到存活对象,然后给存活对象打个标记,最终在清理的时候,如果一个对象没有任何标记,就表示这个对象不可达,需要被清理。而标记算法就是使用三色标记算法。一般使用白色、黑色和灰色来表示。

  • 白色:说明这个对象没有被标记过,在初始阶段,所有对象都是白色,整个过程枚举完最后仍是白色的对象会被当做垃圾对象被清理。
  • 灰色:这个对象正在被标记,但是这个对象直接引用的对象中,至少还有一个没有被标记过。
  • 黑色:对象和他直接引用的所有对象都被标记过,对直接引用的对象下一级引用不做要求,比如A只引用了B,B引用了C、D,那么只要A和B都被标记过,A就是黑色,即使B所引用的C或D还没有被访问到,此时B就是灰色。

根据定义jvm中三色标记算法大致流程是:

  1. 首先从GC Roots开始标记,他们所有直接引用对象变成灰色,自己本身变为黑色(GC Roots对象本身不是垃圾),这里我们用队列去存储灰色对象,把这些灰色对象放到队列中。
  2. 然后从队列中取出灰色对象继续进行分析:将这个对象所有直接引用变成灰色,放入队列中,然后这个对象变为黑色;如果没有直接引用就直接变为黑色。
  3. 继续从队列中取出一个灰色对象,重复第二步,一直到灰色队列为空。
  4. 分析完后,仍然是白色的对象,就是不可大对象,可以作为垃圾被回收。
  5. 最后重置标记状态。

下面提供一个例子,加深下印象:

刚开始所有对象都是白色

三色标记初始阶段(标记的初始解读,不是CMS的初始标记),所有GC Roots直接引用(A、B)变成灰色,放入队列中,GC Roots变成了黑色

然后从灰色队列中取出一个灰色对象进行标记,比如A、将他直接引用C、D变成灰色,放入队列,A因为已扫描完它的直接引用对象,所以变成黑色:

继续从队列中取出灰色对象B,但是E没有直接引用其他对象,将B标记为黑色:

根据上述步骤,取出C 、D 对象进行分析,他们都没有直接引用其他对象,那么就变为黑色:

最终分析标记结束后,还有一个E对象是白色,说明此E 对象是一个垃圾对象,不可访问,可以被清理掉。

3.2三色标记的缺陷
  • 多标-浮动垃圾(标记为不是垃圾对象,变成了垃圾)

如果整个标记过程是STW的,那么没有任何问题,但是并发标记过程中,用户线程也在运行,那么对象引用关系很可能发生变化,进而导致前面提到过的两个问题的出现。

比如垃圾回收线程标记回到上面的这个状态:

此时E对象已经被标记为黑色,表示不是垃圾,不会被清除,因为处在并发标记阶段,同一时刻某个用户线将GC Roots和B对象之间的关系断开了(objRoots.b = null;),如图:

很显然,B对象变为了垃圾对象,但是由于之前被标记为黑色,就不会被当作垃圾回收,这种问题称之为浮动垃圾。

浮动垃圾的问题,影响不大,即使本次不清理,下次GC也会被清理,而且在并发清理阶段也会产生所谓的浮动垃圾,因为用户线程也在不断地断开引用,影响不大。

  • 漏标-错杀问题(标记为垃圾对象,变成了非垃圾)

如果一个非垃圾对象,变成了垃圾,后果就比较严重,再回到上面的状态:

这里标记线程执行到分析B对象,但是刚好发生线程切换,操作系统调度用户线程来运行,而用户线程先执行A.f = E;那么引用关系变成了

用户线程做完上述动作,GC线程重新开始运行,按照之前的流程继续走,从对类中取出B对象,发现对象没有直接引用,那么B对象变成了黑色:

接着继续取出 C、D 三个灰色对象,他们没有直接引用,那么变为黑色对象:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MyBatisPlus常用注解

目录 一、TableName 二、TableId 三、TableField 四、TableLogic 一、TableName 在使用MyBatis-Plus实现基本的CRUD时,我们并没有指定要操作的表,只是在Mapper接口继承BaseMapper时,设置了泛型User,而操作的表为user表 由此得出…

飞天使-k8s知识点22-kubernetes实操7-ingress

文章目录 ingress环境准备准备service和pod验证效果 https 代理效果 ingress 在 Kubernetes 中,Ingress 是一种 API 对象,它管理外部访问集群内部服务的规则。你可以将其视为一个入口,它可以将来自集群外部的 HTTP 和 HTTPS 路由到集群内部的…

海思3559 yolov5 wk模型部署笔记

文章目录 安装3559工具链编译opencv编译项目总结 安装3559工具链 将3559工具链copy到虚拟机上,并解压得到安装包 解压: tar -zxvf aarch64-himix100-linux.tgz解压后会得到安装包文件夹: 安装工具链: sudo ./aarch64-himix100…

用 Python 自动化处理无聊的事情

“编程最棒的部分就是看到机器做一些有用的事情而获得的胜利。用 Python 将无聊的事情自动化将所有编程视为这些小小的胜利;它让无聊变得有趣。” Hilary Mason,数据科学家兼 Fast Forward Labs 创始人 “我很享受打破东西然后把它们重新组合起来的乐趣…

SPSSAU【文本分析】|文本聚类

SPSSAU共提供两种文本聚类方式,分别是按词聚类和按行聚类。按词聚类是指将需要分析的关键词进行聚类分析,并且进行可视化展示,即针对关键词进行聚类,此处关键词可以自由选择。按行聚类分析是指针对以‘行’为单位进行聚类分析&…

陈世元:被保送中科院,两次被裁,人生不能老是按部就班的走下去,需要冒险,尝试一下新的东西

《程客有话说》是我们最新推出的一个访谈栏目,邀请了一些国内外有趣的程序员来分享他们的经验、观点与成长故事,我们尝试建立一个程序员交流与学习的平台,也欢迎大家推荐朋友或自己来参加我们的节目,一起加油。 本期我们邀请的程…

【Qt学习】QLineEdit 控件 属性与实例(登录界面,验证密码,正则表达式)

文章目录 1. 介绍2. 实例使用2.1 登录界面2.2 对比两次密码是否相同2.3 通过按钮显示当前输入的密码(并对2.2进行优化)2.4 结语 3. 正则表达式3.1 QRegExp3.2 验证输入内容 4. 资源代码 1. 介绍 关于 QLineEdit 的详细介绍,可以去查阅官方文…

Web安全之浅见

备注:这是我在2017年在自己的网站上写的文章,今天迁移过来。 昨天去参加了公司组织的一个关于网络安全的培训,了解了很多关于网络安全方面的知识,也才意识到网络安全是一项极其重要的领域。 本篇文章主要聊聊Web安全。不过我对于网…

vue3使用pinia-plugin-persistedstate 持久化不生效的问题

如下图所示,需要在路由拦截器里面写。不然一个都不生效。 【即使以前生效的,在下图【红框】中定义一下,也会失效。得挪到路由拦截器里面才行】 终于出来了

【GPTs分享】每日GPTs分享之Canva

简介 Canva,旨在帮助用户通过Canva的用户友好设计平台释放用户的创造力。无论用户是想设计海报、社交媒体帖子还是商业名片,Canva都在这里协助用户将创意转化为现实。 主要功能 设计生成:根据用户的描述和创意需求,生成定制的设…

MyBatis-Plus 优雅实现数据加密存储

文章目录 前言一、数据库字段加解密实现1. 定义加密类型枚举2. 定义AES密钥和偏移量3. 配置定义使用的加密类型4. 加密解密接口5. 解密解密异常类6. 加密解密实现类6.1 AES加密解密实现类6.2 Base64加密解密实现类 7. 实现数据库的字段保存加密与查询解密处理类8. MybatisPlus配…

Sora热潮下,如何充分利用AI减少人工测试需求?

近日,OpenAI发布视频生成模型Sora,再次引发全球科技圈讨论热潮。Sora可以根据用户输入的简短文本指令,生成长达1分钟的高清视频,视频画面具有真实感,带有些许电影质感。 根据IDC的预测,未来五年内&#xff…

Java项目:20 基于SSM实现的支教管理系统

作者主页:舒克日记 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 ssm支教管理系统(前台后台) 前台角色:支教学校志愿者 支教学校功能模块:支教学校查询报名职位发布已…

Android横竖屏切换configChanges=“screenSize|orientation“避免activity销毁重建,Kotlin

Android横竖屏切换configChanges"screenSize|orientation"避免activity销毁重建,Kotlin 如果不在Androidmanifest.xml设置activity的: android:configChanges"screenSize|orientation" 那么,每次横竖屏切换activity都会…

【鸿蒙 HarmonyOS 4.0】数据持久化

一、数据持久化介绍 数据持久化是将内存数据(内存是临时的存储空间),通过文件或数据库的形式保存在设备中。 HarmonyOS提供两种数据持久化方案: 1.1、用户首选项(Preferences): 通常用于保存应用的配置信息。数据通…

如何使用Express框架构建一个简单的Web应用

在这个数字化时代,Web应用的需求越来越多样化和复杂化。在前端开发领域,Express框架作为一个快速、灵活的Node.js Web应用程序框架,拥有强大的功能和丰富的生态系统,深受开发者们的青睐。本篇博客将带您一步步探索如何使用Express…

JS进阶——解构赋值

数组解构 基本: let [a, b, c] [1, 2, 3]; // a 1 // b 2 // c 3 可嵌套 let [a, [[b], c]] [1, [[2], 3]]; // a 1 // b 2 // c 3 可忽略 let [a, , b] [1, 2, 3]; // a 1 // b 3 不完全解构 let [a 1, b] []; // a 1, b undefined 剩余运…

LLMChain使用 | RouterChain的使用 - 用本地大模型搭建多Agents

单个本地大模型搭建参考博客 单个Chain:面对一个需求,我们需要创建一个llmchain,设置一个prompt模板,这个chain能够接收一个用户input,并输出一个结果;多个Chain:考虑到同时面对多个需求&#x…

【计算机网络】网络基础知识

一. 网络发展史 独立模式(单机模式):计算机之间相互独立,各自拥有独立的数据。 网络互连:将多台计算机连接在一起,完成数据共享。 随着时代的发展,越来越需要计算机之间进行互相通信&#…

#1.4w字长文#仿抖音项目架构设计与实现

一、项目介绍 本文介绍了一个Web端短视频应用,致力于为用户提供交互友好、功能完备的短视频浏览体验和直播体验。 集成了Gorse推荐算法,旨在为用户提供更个性化的推荐视频流和更权威的热门视频流。接入大模型,通过对视频内容进行语言分析&a…