IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Golang-垃圾回收-三色标记法 -> 正文阅读

[Java知识库]Golang-垃圾回收-三色标记法

1.垃圾回收回顾

1.1 概念:

垃圾回收算法目前常见的也就那么几种,如:标记-清除、标记-复制、标记-整理。在此基础上可以采用分代管理(新生代、老年代、永久代),每代采用不同的垃圾回收算法,以提高整体的回收效率。

1.2 步骤:

  • 标记存活对象和可回收对象(可达性分析算法、计数法)
  • 对可回收对象采用进行垃圾回收处理

1.3 标记方法:

  • 可达性分析算法:可达性分析算法是以根对象集合(GC Roots)为起始点,按照从上至下的方式进行搜索,搜索所走过的路径称为引用链(Reference Chain),通过判断对象与GC Roots之间是否有引用链相连来判断该对象是否需要回收,如果目标对象没有任何引用链相连,则是不可达的,就意味着该对象已经死亡,可以标记为垃圾对象。
  • 引用计数算法:为每一个对象分配一个计数器,当这个对象被另一个对象引用时,这个计数器就加一;当被另一个对象取消引用时,计数器就减一。当这个计数器的值为零时,就表示当前对象没有被任何对象所引用,那么这个对象就可以被垃圾回收器进行回收了。该方法实现起来非常简单,但是有一个致命的缺点,那就是不能解决各对象之间循环引用的问题。

2.三色标记法

2.1 基本概念:

根据可达性分析,从GC Roots开始进行往下进行,可达的则为存活对象
在这里插入图片描述
我们把搜索过程中遇到的对象,按是"否访问过"这个条件标记成以下三种颜色:

  • 白色:尚未访问过。
  • 黑色:本对象已访问过,而且本对象引用到的其他对象也全部访问过了。
  • 灰色:本对象已访问过,但是本对象引用到的其他对象尚未全部访问完。

2.2 过程

  1. 开始时,将所有的对象都加入到【白色集合】中去。
  2. 将GC roots从【白色集合】中转移到【灰色集合】中去
  3. 将GC roots直接引用到的所有对象转移到【灰色集合】中,同时将GC roots转移到【黑色集合】中去。
  4. 从【灰色集合】中获取对象:
    将该对象 引用到的 其他对象 全部挪到 【灰色集合】中;
    将该对象 挪到 【黑色集合】里面。
  5. 重复步骤3,直至【灰色集合】为空时结束。
  6. 结束后,仍在【白色集合】的对象即为GC Roots 不可达,可以进行回收。

第一步程序将会Stop The World,这时候对象间的引用是不会发生变化的,可以轻松完成标记。而当需要支持并发标记时,即标记期间应用线程还在继续跑,对象间的引用可能发生变化,多标漏标的情况就有可能发生。

2.3 多标-浮动垃圾

在这里插入图片描述
如上图所示,假设引用链已经走到E(灰色集合)了,这个时候应用执行了objD.fieldE = null,此时D与E之间的引用链将断开,此刻之后,对象E/F/G是“应该”被回收的。然而因为E已经变为灰色了,其仍会被当作存活对象继续遍历下去。最终的结果是:这部分对象仍会被标记为存活,即本轮GC不会回收这部分内存。
这部分本应该回收 但是 没有回收到的内存,被称之为“浮动垃圾”。浮动垃圾并不会影响应用程序的正确性,只是需要等到下一轮垃圾回收中才被清除。

另外,针对并发标记开始后的新对象,通常的做法是直接全部当成黑色,本轮不会进行清除。这部分对象期间可能会变为垃圾,这也算是浮动垃圾的一部分。

2.4 漏标-读写屏障

在这里插入图片描述
如上图所示,假设搜索到引用链已经走到E(灰色集合),此时执行代码:

var G = objE.fieldG; 
objE.fieldG = null;  // 灰色E 断开引用 白色G 
objD.fieldG = G;  // 黑色D 引用 白色G

此时切回GC线程继续跑,因为E已经没有对G的引用了,所以不会将G放到灰色集合;尽管因为D重新引用了G,但因为D已经是黑色了,不会再重新做遍历处理。
最终将会导致G会一直停留在白色集合中,最后被当作垃圾进行清除。这直接影响到了应用程序的正确性,是不可接受的。

漏标需同时满足以下两个条件:
1.【灰色集合】对象断开对【白色集合】对象的引用。
2.【黑色集合】对象在GC期间重新引用【白色对象】

解决漏标—读写屏障

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-02-26 11:16:56  更:2022-02-26 11:20:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:26:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码