假设我有以下类(class),如下所述:
class A {
private B b;
public A {
b = new B(this);
}
}
class B {
private C c;
private A a;
public B(A a) {
this.a = a;
c = new C(this);
}
public removeRefereceToC() {
c = null;
}
}
class C {
private B b;
public C(B b) {
this.b = b;
}
}
如果我们看一下引用图,A 引用 B(并且 B 引用 A),B 引用 C(并且 C 引用 B)。现在,如果我们调用B的方法removeReferenceToC(),那么B对对象C的引用将被消除,但C仍然会引用B。此时C是否有资格进行垃圾回收?
我不确定的原因是,由于引用 C 的方向无法再从 B 到达,这让我认为 C 符合垃圾回收的条件,但是 C 仍然引用 B 的事实让我很困惑离开。
那么如果 B 取消对 C 的引用,C 是否有资格进行垃圾回收?
编辑: 该问题被标记为重复。我认为我的问题和之前回答的问题之间的主要区别可以总结为: 之前的问题: A -> B <=> C 然后从 A 到 B 的引用被删除,剩下 A B <=> C
我的问题: A <=> B <=> C 然后从 B 到 C 的引用被删除,留下 A <=> B <- C
最佳答案
您在技术方面想得太多了。垃圾收集被定义为能够回收无法访问对象存储的任何措施。
Java Language Specification §12.6.1定义:
A reachable object is any object that can be accessed in any potential continuing computation from any live thread.
定向引用是运行代码如何访问对象的一种方式,事实上,遍历这些引用是垃圾收集器实现检测对象可达性的典型方式,但必须强调的是,即使存在,例如如果没有“潜在的持续计算”读取它,则引用对象的局部变量不足以阻止其垃圾回收。
这就是 JVM 优化器转换代码、消除未使用的变量和死代码时实际发生的情况。
链接部分还明确指出:
Optimizing transformations of a program can be designed that reduce the number of objects that are reachable to be less than those which would naively be considered reachable.
不要被这些技术细节分散注意力,只要知道只有访问对象的可能性与确定它不是垃圾相关就足够了。因此,无论对象如何与引用链接,如果没有 Activity 线程可以访问它们,它们都是垃圾。
关于java - Java中的循环引用和垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41600880/