引用计数算法
-
在对象中添加一个引用计数器,每当有一个地方引用它时
-
计数器值就加一;当引用失效时,计数器值就减一;
-
任何时刻计数器为零的对象就是不可能再被使用的。
==引用计数算法的缺陷==
-
如下面代码,两个对象互相引用导致无法回收♻️
-
对象objA和objB都有字段instance,赋值令 objA.instance=objB及objB.instance=objA,
-
除此之外,这两个对象再无任何引用,实际上这两个对象已 经不可能再被访问,
-
但是它们因为互相引用着对方,导致它们的引用计数都不为零,引用计数算法也 就无法回收它们。
可达性分析算法
==基本思路==
-
通过一系列称为“GC Roots”的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,
-
搜索过程所走过的路径称为“引用链”(Reference Chain),如果某个对象到GC Roots间没有任何引用链相连,
-
或者用图论的话来说就是从GC Roots到这个对象不可达时,则证明此对象是不可能再被使用的。
三色标记📌
有三种颜色
- 白色:代表对象还没有被垃圾收集器访问过,最开始所有都是白色,但是在结束阶段,如果还是白色,那
么就不可达
-
黑色:代表对象已经被垃圾收集器访问过,并且所有引用已经被扫描过,是安全存活的
-
灰色:代表对象已经被垃圾收集器访问过,但是这个对象至少存在一个引用还没被扫描过
-
最初的状态:只有GC Roots是黑色的
- 扫描过程中,从黑色变为灰色
- 扫描完成后,黑色就是活着的对象,白色就是已经消亡可以回收♻️
- 但是如果现在用户线程在标记进行时并发修改了引用关系,灰色的引用被断开,又与黑色对象建立了引用
- 切断以后黑色对象,因为黑色对象不会重新扫描,这样就会扫描结束后,被黑色引用的依然是白色,这个对象就「消失了」
对象消失情况
-
当插入一条或多条从黑色对象到白色对象的新引用
-
删除了全部从灰色到白色的直接或间接引用
两种解决方案
增量更新
-
破坏第一个条件,当有黑色对象新的引用白色对象时,就把插入的引用记录下来,
-
等并发扫描过后,再讲这些记录的应用关系中的黑色对象作为跟,重扫一遍
直接或间接引用
两种解决方案
增量更新
-
破坏第一个条件,当有黑色对象新的引用白色对象时,就把插入的引用记录下来,
-
等并发扫描过后,再讲这些记录的应用关系中的黑色对象作为跟,重扫一遍