两个对象引用指向彼此

时间:2013-07-11 07:05:24

标签: java

在目标C中,两个不同的引用可能相互指向。

但这在Java中是否可行?我的意思是,两个对象引用是否可以互相指向?如果可能的话,他们什么时候会被垃圾收集?

而且,在嵌套类的情况下,两个对象(内部类和外部类)相互链接 - 这些对象如何被垃圾收集?

3 个答案:

答案 0 :(得分:27)

我假设您正在讨论循环引用。如果无法通过从GC根开始的链到达,则Java的GC会将对象视为“垃圾”。即使对象可能指向彼此形成一个循环,如果从根切断它们仍然符合GC的条件。

Java中有四种GC根:

  1. 局部变量由一个线程堆栈保持活动状态。这不是真实对象虚拟参考,因此不可见。对于所有意图和目的,局部变量是GC根。

  2. 活动Java线程始终被视为活动对象,因此是GC根。这对于线程局部变量尤其重要。

  3. 静态变量由其类引用。这一事实使他们成为事实上的GC根源。类本身可以被垃圾收集,这将删除所有引用的静态变量。当我们一般使用应用程序服务器,OSGi容器或类加载器时,这一点特别重要。

  4. JNI引用是本机代码作为JNI调用的一部分创建的Java对象。这样创建的对象是专门处理的,因为JVM不知道它是否被本机代码引用。这些对象代表了一种非常特殊的GC根形式。

  5. 您还可以阅读here了解更多信息。

    enter image description here

答案 1 :(得分:5)

是的,你可以这样做。像这样:

class Pointy {
    public Pointy other;
}

Pointy one = new Pointy();
Pointy two = new Pointy();
one.other = two;
two.other = one;

当两个对象没有被彼此指向的任何对象或其他与当前运行代码“无法访问”的对象时,它们被垃圾收集。 Java垃圾收集器是"tracing" garbage collectors,这意味着他们可以发现这类问题。

相反,reference-counted系统(如Objective C没有“现代”垃圾收集 - 我不知道默认是什么)通常无法检测到这类问题,因此对象可能会被泄露。 / p>

答案 2 :(得分:3)

当然,您可以让对象互相引用。您可以简单地将两个对象中的this指针相互传递,这完全有效。

但是,这并不意味着仍然可以从GC根目录访问对象。可以把它想象成(图)树。如果从主干中切断完整的分支,则无论涉及多少个对象或维护彼此的引用,整个分支都会丢失。