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 三个灰色对象,他们没有直接引用,那么变为黑色对象:

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

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

相关文章

【快速搞定Webpack5】基本配置及开发模式介绍(二)

在开始使用webpack之前么,我们需要对Webpack的配置有一定的认识。 一、5大核心概念 1. enty(入口) 指示webpack从哪个文件开始打包 2. output(输出) 指示webpack打包完的文件输出到哪里去,如何命名等 …

适配器模式:转换接口,无缝对接不同系统

文章目录 **一、技术背景与应用场景****为什么使用适配器模式?****典型应用场景包括但不限于:** **二、适配器模式定义与结构****三、使用步骤举例****四、优缺点分析****总结** 一、技术背景与应用场景 适配器模式在软件设计中扮演着桥梁角色&#xff…

Linux(五)__系统管理

介绍 通常, Windows 中使用"任务管理器"主要有 3 个目的: 利用"应用程序"和"进程"标签来査看系统中到底运行了哪些程序和进程;利用"性能"和"用户"标签来判断服务器的健康状态&#xff1…

前端构造树算法优化

背景 开发过程中遇到后台返回的平铺数据,需要自己根据数据的parent_id将其构造成一套树结构,首先采用递归的方式对数据进行组装。 但后续使用中发现,如果遇到数据量较大(40000)后,该方法的处理耗时明显过长,且导致页面…

怎样重置ubuntu mysql8密码

密码很难记住,所以如果您忘记了 MySQL root 密码,幸运的是,有一种方法可以更改它。这篇文章是为您而写的,在这篇文章结束时,您将成功更改 MySQL 的密码。 本博客演示了如何在 Ubuntu 上重置使用包管理器安装的 MySQL …

vue项目调用摄像头实现拍照功能

目录 1.功能需求 2.API 3.完整代码 4.效果 5.遇到问题 1.功能需求 需求:下面需求图 本来应该使用小程序做,但是为了以后复用考虑,决定使用vue嵌入小程序中。 所以需求就是 调用手机摄像头 实现拍照打卡功能(电脑通用) 2.API …

物联网平台构成与边缘计算

物联网平台 物联网平台系统通常由以下组件构成: 物联网设备: 这些是连接到物联网平台的传感器、设备或物品。它们可以是各种物联网设备,如传感器、执行器、智能设备等。 通信协议: 物联网设备使用各种通信协议与物联网平台进行通…

介绍一下scrapy中items.py,middlerwares.py,pipelines.py,settings.py的作用与简单示例。

在Scrapy框架中,items.py、middlewares.py、pipelines.py和settings.py都是用于实现不同功能的重要模块。以下是它们的作用和一些常见示例: items.py items.py 文件定义了你的项目中需要提取的数据的数据结构。每个爬虫项目都可以定义一个或多个Item类…

React 19即将发布,新增4个Hook函数

近日,React 团队发布消息称,不会载发布 v18.3版本了,而是即将重点放在React v19 版本。新版本将退出四个新的 hook——旨在解决 React 中两个常见的痛点:数据获取和表单处理。虽然这些 hook 目前作为实验性 API 在 React 预览版本中可用,但它们预计将成为 React 19 的稳定…

创建谷歌浏览器插件的具体步骤

创建谷歌浏览器(Chrome)插件需要遵循一系列的步骤。以下是一个基本的指南,用于创建一个简单的Chrome插件: 1. 设置项目文件夹 创建一个新的文件夹,用于存放插件的所有文件。 2. 创建manifest.…

【Redis】Redis的数据分布算法

一共有五种算法,分别为:哈希算法、一致性哈希算法、带有限负载的一致性哈希算法、虚拟节点一致性哈希算法、虚拟槽分区 哈希算法 思想:根据某个key的值或者key 的哈希值与当前可用的 master 节点数取模,根据取模的值获取具体的服…

机器学习 -- 矩阵和向量

场景 在之前的knn算法和余弦算法等算法中,都有很重要的概念,叫做矩阵和向量。这个是机器学习中很重要的概念。今天来深入学习一些矩阵和向量的一些知识。 向量(Vector) 向量是一个有序的数字列表,可以在几何中表示为从原点出发的箭头。在机…

halcon 标定多元点标定板、棋盘格映射矫正图像、矫正失真图像

一、标定多圆孔标定 其理论与棋盘格 和圆孔都是一样的,不一样的地方就是定方向的方式不一样。如图 2、结果 read_image (CalibImage, ./circle/1.png) get_image_size (CalibImage, Width, Height) dev_close_window () dev_open_window_fit_image (CalibImage, 0…

推荐一款Vite中加载svg的小工具

最近开发中使用到一个好玩的Vite三方小插件vite-plugin-svg-icons很实用,可以辅助我们开发过程中快速加载svg小图标。其原理是在Vite编译器的时候通过一次性的DOM操作将SVG插入DOM结构中,然后通过使用内联SVG进行加载访问,极大的方便了我们的小图标引用模式。 若只是少量的s…

PE 资源表-字符串

最近在写PE加载代码,写到LoadStringA时一直找不到字中的ID,网上搜索的资源只分析三层目录,之后的找不相关资料,只好自己分析。 资料显示pe资源表 分三层目录,之后是节点,再指向数据, 第二层的…

“成像光谱遥感技术中的AI革命:ChatGPT应用指南“

遥感技术主要通过卫星和飞机从远处观察和测量我们的环境,是理解和监测地球物理、化学和生物系统的基石。ChatGPT是由OpenAI开发的最先进的语言模型,在理解和生成人类语言方面表现出了非凡的能力。本课程重点介绍ChatGPT在遥感中的应用,人工智…

2024牛客寒假算法基础集训营4(视频讲解题目)

2024牛客寒假算法基础集训营4&#xff08;视频讲解题目&#xff09; 视频链接ABCDEFG、H&#xff08;下面是hard版本的代码两个都可以过&#xff09; 视频链接 2024牛客寒假算法基础集训营4&#xff08;视频讲解题目&#xff09; A #include<bits/stdc.h> #define en…

【教程】N2N V3内网穿透、异地组网,包括Win/Linux/Android,包括不同内网实现adb远程连接

目录 一、背景 二、Linux 配置 并运行 N2N - Supernode (必选) 三、Linux -- 配置 并运行 N2N - 边缘节点配置 Edge(可选步骤) 四、Windows -- 配置 并运行 N2N - 边缘节点配置 Edge (可选步骤) (一)配置 TAP 虚拟网卡 (二)配置 N

C++:C++入门基础

创作不易&#xff0c;感谢三连 &#xff01;&#xff01; 一、什么是C C语言是结构化和模块化的语言&#xff0c;适合处理较小规模的程序。对于复杂的问题&#xff0c;规模较大的程序&#xff0c;需要高度的抽象和建模时&#xff0c;C语言则不合适。为了解决软件危机&#xff…

子网络划分与互通,上网行为审计

网络环境需求:在办公网络环境中,由于公司部门的划分,以及服务器、电脑、手机等设备类型,一般都需要划分多个网段,便于进行网络管理,并提升网络通信效率。各个子网段管理员控制设备的接入,子网段之间需要进行局域网通信,发送消息和文件,通常使用飞秋。服务器网段,禁止…