文章目录

    • 前言
  • 什么是垃圾回收
    • JAVA的垃圾回收回顾
    • GO的垃圾回收学习
      • **三色标记法(tricolor mark-and-sweep algorithm)**
        • Dijkstra方法(插入屏障,强三色,Go1.7之前)
        • Yuasa方法(删除屏障,弱三色,Go1.8)
        • Hybrid方法(混合写屏障)
    • 总结
    • 文章致谢

前言

​ 众所周知,一门优秀的语言总会需要考虑很多点,比如说性能、内存、并发处理等,把其语言开发到一个高度。这一期我们学习的内容是内存方面的,并且结合java和go语言去阐述经典的内存垃圾对象回收算法。

什么是垃圾回收

在计算机科学中,垃圾回收(英语:Garbage Collection,缩写为GC)是指一种自动的存储器管理机制。当某个程序占用的一部分内存空间不再被这个程序访问时,这个程序会借助垃圾回收算法向操作系统归还这部分内存空间。

通常占用程序空间都是一些运行对象,对象可包含的数据在一定限度是非常占用内存空间的,在某一时刻,就会达到操作系统规划的内存空间,若数量多起来了,就会超过该空间导致机器卡顿或者宕机情况发生。

我们思考的方向便是既要最大化的利用计算机性能,又要保护计算机正常稳定的运转下去,就如同大自然一样,循环利用资源,这样才有可能实现持久化程序生态。

现在业界垃圾回收器可以总结为两种收集器

引用计数收集器
最早的也是最简单的垃圾回收实现方法,这种方法为占用物理空间的对象附加一个计数器,当有其他对象引用这个对象时计数器加一,反之引用解除时减一。这种算法会定期检查尚未被回收的对象的计数器,为零的话则回收其所占物理空间,因为此时的对象已经无法访问。这种方法无法回收循环引用的存储对象。

跟踪收集器
近现代的垃圾回收实现方法,这种算法会定期遍历它管理的内存空间,从若干根储存对象开始查找与之相关的存储对象,然后标记其余的没有关联的存储对象,最后回收这些没有关联的存储对象占用的内存空间。

这两个收集器的思想也会在java和go的垃圾回收器中有所体现,下面开始介绍。

JAVA的垃圾回收回顾

引用计数法

将资源(可以是对象、内存或磁盘空间等等)的被引用次数保存起来,当被引用次数变为零时就将其释放的过程。使用引用计数技术可以实现自动资源管理的目的。同时引用计数还可以指使用引用计数技术回收未使用资源的垃圾回收算法。

优点:实现简单,垃圾对象便于辨识;判定效率高,回收没有延迟性。

缺点:循环引用会造成垃圾对象无法回收

例子:

public class GcDemo {public void demo {//分为6个步骤GcObject obj1 = new GcObject(); //Step 1GcObject obj2 = new GcObject(); //Step 2obj1.instance = obj2; //Step 3obj2.instance = obj1; //Step 4obj1 = null; //Step 5obj2 = null; //Step 6}
}class GcObject{public Object instance = null;
}

实现图如下所示

可以看出即便obj1和obj2断开了引用链的链接但依然存在内部引用关系链,这样如果大家看到这里还是很可能不明不白的,比如说为啥计数器是2而不是1这样。我们得从底层出发,这里简单的介绍下关于java的内存模型,结合内存模型来说下。

Step1:GcObject实例1的引用计数加1,实例1的引用计数=1;

Step2:GcObject实例2的引用计数加1,实例2的引用计数=1;

Step3:GcObject实例2的引用计数再加1,实例2的引用计数=2;

Step4:GcObject实例1的引用计数再加1,实例2的引用计数=2;

执行到Step 4,则GcObject实例1和实例2的引用计数都等于2。

断开引用后

会发现实际上obj1和obj2均不指向Java的堆,但是在堆内实例对象还会相互引用,计数器还是没有为零,这导致实际上应该回收obj1和obj2的没有回收,导致内存泄露。

可达性分析法

可达性分析算法,又叫根搜索算法或者追踪性垃圾收集

可达性分析算法是以根对象集合(GC Roots)为起始点,按照从上至下的方式搜索被根对象集合所连接的目标对象是否可达。使用可达性分析算法后,内存中的存活对象都会被根对象集合直接或间接连接着,搜索所走过的路径称为引用链(Rererence Chain)。如果目标对象没有任何引用链相连,则是不可达的,就意味着该对象已经死亡,可以标记为垃圾对象。在可达性分析算法中,只有能够被根对象集合直接或者间接连接的对象才是存活对象。

优点:解决引用计数器所不能解决的循环引用问题。 即便对象a和b相互引用,只要从GC Roots出发无法到达a或者b,那么可达性分析便不会将它们加入存活对象合集之中。

缺点:由于需要从GC Roots开始逐个检查引用,所以耗时是缺点之一,而且在此期间,需要保证整个执行系统的一致性,对象的引用关系不能发生变化,所以会导致GC进行时必须停顿所有Java执行线程(STW)。(遍历耗时长)

GO的垃圾回收学习

三色标记法(tricolor mark-and-sweep algorithm)

首先将对象用三种颜色表示,分别是黑色、灰色和白色。最开始所有对象都是白色的,然后把其中全局变量和函数栈里的对象置为灰色。第二步把灰色的对象全部置为黑色,然后把原先灰色对象指向的变量都置为灰色,以此类推。等发现没有对象可以被置为灰色时,所有的白色变量就一定是需要被清理的垃圾了。

遍历集合,判断垃圾对象回收步骤:

Step 1: 创建:黑、灰、白 三个集合。

Step 2: 将所有对象放入白色集合中。

Step 3: 从根节点开始遍历所有对象,把遍历到的对象从白色集合放入灰色集合(备注:这里放入灰色集合的都是根节点的对象)。

Step 4: 遍历灰色集合,将灰色对象引用的对象从白色集合放入灰色集合,然后将分析过的灰色对象放入黑色集合。

Step 5: 重复以上的步骤直到对象遍历结束

虽然这样很容易理解,但是也是理想情况回收,真正在我们的程序运行中会有很多情况发生。这些情况就会造成该对象应该不被回收但是被错误回收,应该被回收的没有被回收。可以总结以下两种问题:多标-浮动垃圾漏标-悬挂指针问题

多标-浮动垃圾

对象之间的引用链断开却没有把其变为可回收对象,反倒作为灰色对象继续存活下去。这部分垃圾对象没有被正确的回收成为“浮动垃圾”。

漏标-悬挂指针问题

指中间对象之间断开引用链后,指向在引用的对象断开的引用对象并没有在做遍历处理,导致对象没有遵循三色原则作为垃圾对象被回收。

Step1:正常遍历,E断开H的引用,但是此时没有将H放入灰色集合,D直接引用H

Step2:继续正常遍历,E变成黑色,F变成灰色,但是由于E断开了H的引用而D是黑色不会再次遍历对H的引用

Step3:H作为白色对象被回收

Ps:所以本想用H的,你给我回收了?

这就是设计最不可被接受的一点。

浅谈垃圾对象回收之《三色标记法》相关推荐

  1. golang 垃圾回收、三色标记法、写屏障

    垃圾回收简称 GC,就是对程序中不再使用的内存资源进行自动回收释放的操作. 常见的垃圾回收算法 引用计数:每个对象维护一个 引用计数,当对象被创建或被其他对象引用时,计数 +1:如果引用该对象的对象被 ...

  2. JVM垃圾回收——三色标记法

    目录 一.什么是三色标记 二.三色标记的过程 三.三色标记的缺点 四.垃圾回收机如何弥补三色标记的缺点 在CMS.G1这种并发的垃圾收集器收集对象时,假如一个对象A被GC线程标记为不可达对象,但是用户 ...

  3. 双/三色标记法的垃圾回收(GC)原理解析和缺陷解决方案(Go,Lua以及jvm的CMS和G1垃圾回收器中使用的回收算法)

    标记-清除算法 go和lua虚拟机以及jvm的CMS和G1垃圾回收器的回收算法的思想均来自于标记-清除算法(Mark-Sweep),它们的gc有重要的两部分: 1.从根节点遍历所有对象,如果可达到,则 ...

  4. java对象头_浅谈java对象结构 对象头 Markword

    概述 对象实例由对象头.实例数据组成,其中对象头包括markword和类型指针,如果是数组,还包括数组长度; | 类型 | 32位JVM | 64位JVM| | ------ ---- | ----- ...

  5. java对象头markword_浅谈java对象结构 对象头 Markword

    概述 对象实例由对象头.实例数据组成,其中对象头包括markword和类型指针,如果是数组,还包括数组长度; | 类型 | 32位JVM | 64位JVM| | ------ ---- | ----- ...

  6. java 对象之间转换_浅谈java对象之间相互转化的多种方式

    浅谈java对象之间相互转化的多种方式,对象,属性,参数,赋值,不支持 浅谈java对象之间相互转化的多种方式 易采站长站,站长之家为您整理了浅谈java对象之间相互转化的多种方式的相关内容. 第一种 ...

  7. 袁萌浅谈C919大飞机(三)

    袁萌浅谈C919大飞机(三) 飞机在天上"飞",究竟是什么力量在托举着它?这种力量足以使其不会从天上掉下来.据说,有人不敢坐飞机去旅行,担心飞机从天上掉下来,人被摔死. 设想一架C ...

  8. 浅谈GPU虚拟化技术(三)GPU SRIOV及vGPU调度

    本系列文章推送门: 阿里云郑晓:浅谈GPU虚拟化技术(第一章) GPU虚拟化发展史  阿里云郑晓:浅谈GPU虚拟化技术(第二章)GPU虚拟化方案之--GPU直通模式 今天一个小伙伴@我说:" ...

  9. 【JVM】三色标记法与读写屏障

    1.概述 首先:CMS和G1都使用了三色标记法 关于垃圾回收算法,基本就是那么几种:标记-清除.标记-复制.标记-整理.在此基础上可以增加分代(新生代/老年代),每代采取不同的回收算法,以提高整体的分 ...

最新文章

  1. HP ML110/120 G7配置阵列卡安装server 2003
  2. oracle11g中rman基本使用方法
  3. 第三方工具监控java进程_前9个免费的Java进程监视工具以及如何选择一种
  4. python爬取全国真实地址_Python3爬虫全国地址信息
  5. python中astr是啥_python的基本操作
  6. 如何优雅的使用 phpStorm
  7. (转)invalidate()和postInvalidate() 的区别及使用
  8. html让时间只展示年月日_JS 如何动态显示当前年月日时分秒-百度经验
  9. 实现加载页Loading Page 的几种方法
  10. 什么叫SYN包,什么是SYN包***?
  11. Synchronized 用法以及和ReetrantLock的区别
  12. 蓝牙LMP剖析(二)
  13. jzoj 5850.【NOIP提高组模拟2018.8.25】e 可持久化线段树+lca
  14. 陕西省土地规划资质办理流程及申请条件
  15. Friedman 检验后的two-tailed Nemenyi test和the two-tailed Bonferroni-Dunn test的关键值
  16. 世界杯,越位,点球,角球等足球相关英语怎么说
  17. 计算机网络系统拓扑图
  18. RealPlayer.11.6.0.14.748 新体验
  19. Paperreading之五 Stacked Hourglass Networks(SHN)和源码阅读(PyTorch版本)
  20. 澳门一出租车司机滥收车费诬告乘客 被中止营业资格

热门文章

  1. linux系统字体放在哪,可以把windows下的字体安装到Linux系统下吗
  2. 留守儿童迎来“AI小伙伴” 金融壹账通携手金融机构落地“加马成长伙伴”
  3. c# 自定义类数组实例化与初始化
  4. 第十一届蓝桥杯C/C++B组 试题E:玩具蛇(题目+题解)
  5. apache poi斜边框线_Apache POI Word - 边框
  6. Low Power概念介绍SRPG Cell
  7. 数据结构 二叉树 增 删 遍历 查询 实现 源码
  8. 研究生选择统计学还是计算机,985学校的数学系的想考好一点的学校的金融经济方面的研究生容易么?专业应该选择统计学还是应用数学?...
  9. android程序怎么导入图片不显示,android – ImageViewZoom中不显示图像
  10. JBL Go 2突然没声按关机键没反应(已解决)