如何判断一个对象是否可以被回收?
程序员文章站
2024-03-17 20:52:16
...
再谈垃圾回收之前,我们应该先谈一下什么是垃圾?
什么是垃圾?
- 简单来说就是内存中已经不在使用到的空间就是垃圾
- 垃圾是指在运行程序中没有任何指针指向的对象,这个对象就是需要被回收的垃圾。
如果不清除垃圾,就会导致内存溢出。
引用计数法
什么是引用计数法?
- 在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器值就加一;任何时刻计数器为0的对象就是不可能被在使用的。
缺点:难以解决循环引用的问题。
public class ReferenceGC {
public Object instance = null;
public static void main(String[] args) {
ReferenceGC A = new ReferenceGC();
ReferenceGC B = new ReferenceGC();
A.instance = B;
B.instance = A;
A = null;
B = null;
System.gc();
}
}
这两个对象互相引用着对方,除此之外两个对象再无任何引用。但是因为他们的引用计数器都不为0,那么引用计数法也就无法判定他们为垃圾。
可达性分析(Reachability analysis)
思路:通过一系列称为“GC Roots”的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”,如果某个对象到GC Roots之间没有任何引用链相连,或者用图论的话来说就是从GC Roots到这个对象不可达时,证明此对象是不可能在被使用的。
- 可达性分析能有效的解决循环引用的问题,防止内存泄漏的发生。
- 如果使用可达性分析算法来判断内存是否可以回收,那么分析工作必须在一个能保障一致性的快照中进行。这点都不能保证的话分析结果的准确性就无法保证。(为什么要STW)。
无论通过引用计数法判断对象的引用数量,还是通过可达性分析算法判断对象是都引用可达,这两种方法都和 引用 离不开关系。