两个对象引用相互指向

13

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

但在Java中是否也可能发生这种情况呢?也就是说,两个对象引用能否互相指向?如果可能的话,它们何时被垃圾回收?

而对于嵌套类,两个对象(内部类和外部类)会相互链接 - 这些对象该如何进行垃圾回收呢?


2
一个对象引用只能指向一个对象。当我们说两个对象引用相互指向时,意味着这两个对象引用彼此指向对方。 - Rohit Jain
哦!我是Java的新手!在嵌套类的情况下,两个对象(内部类和外部类)彼此链接。如果我说得有道理,这两个对象如何被垃圾回收? - Sai Chaithanya
3个回答

37
我假设你在谈论循环引用。Java的垃圾回收器(GC)会认为对象是“垃圾”,如果它们不能通过从GC根开始的链路访问。即使对象相互指向形成一个循环,如果与根断开联系,仍然有资格被GC回收。
Java有四种类型的GC根:
1. 局部变量由线程的堆栈保持活动状态。这不是一个真正的虚拟对象引用,因此不可见。实际上,局部变量是GC根。 2. 活动的Java线程始终被视为活动对象,因此它们是GC根。这对于线程本地变量尤其重要。 3. 静态变量由它们的类引用。这个事实使它们成为事实上的GC根。类本身可以被垃圾回收,这将删除所有引用的静态变量。当我们使用应用程序服务器、OSGi容器或一般的类加载器时,这尤为重要。 4. JNI引用是本地代码作为JNI调用的一部分创建的Java对象。因为JVM不知道这些对象是由本地代码引用还是没有引用,所以这些对象被特别处理。这些对象代表一种非常特殊的GC根。
您还可以阅读这里获取更多信息:http://www.artima.com/insidejvm/ed2/gc.html

这是否意味着如果垃圾收集器收集了类并且程序在将来另一次使用它,静态初始化程序可以在单个类中运行多次? - CausingUnderflowsEverywhere

9

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

class Pointy {
    public Pointy other;
}

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

当两个对象除了彼此之外没有被其他东西指向,或者其他从当前运行代码中“无法访问”的对象指向它们时,它们将被垃圾回收。Java垃圾回收器是"跟踪式"垃圾回收器,这意味着它们可以发现这种问题。
相反,引用计数系统(例如没有“现代”垃圾回收的Objective C-我不知道默认值是什么)通常无法检测这种问题,因此对象可能会泄漏。

4
当然,你可以让对象引用彼此。你可以在两个对象中简单地相互传递“this”指针,这是完全有效的。
但是,这并不意味着对象仍然可以从GC根访问。可以将其���为一棵(图形)树。如果你从树干上截断了一整个分支,无论涉及多少对象或者这些对象彼此维持着多少引用,整个分支都会消失。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接