java - Java中的循环引用和垃圾收集

标签 java garbage-collection

假设我有以下类(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/

相关文章:

Java 8 lambda 闭包和 GC

Java String 对象没有按时收集垃圾

java - 十进制转二进制java程序

java - StAX 内存不足错误

java - Jvm native 代码编译疯狂 - 即使在编译代码后,我似乎也会在一段时间内遭受奇怪的性能损失。为什么?

android - 何时何地调用 GC_CONCURRENT?

java - Pivot gemfire 索引创建花费了太多时间

java - Vaadin - 将数据传递到不同的 UI

java - 如何从 fxml TextField 获取文本

java - 何时显式地将对象设置为 null 以使 Java 中的内存可回收?