Java垃圾收集器是否会回收包含对其他对象的引用的非引用对象

时间:2013-04-02 13:08:36

标签: java list garbage-collection

当我学习 LinkedList 数据结构时会出现这个问题。假设每个链接(或节点)由包含两个字段的对象表示, data & next 指向下一个链接。如果我想删除特定节点,显然我将更新之前链接的 next 字段。但是我应该将已删除链接的 next 字段设置为null,以确保它将被垃圾收集器回收吗?

如果我的描述不清楚,我会尝试概括(或简化)我的问题。假设类 A 的对象 a1 有一个字段,该字段引用同一个类的另一个对象 a2 。如果没有对象 a1 的引用,它是否有资格使用垃圾收集器?或者我们必须在 a1 中明确设置参考字段为 null ? (不关心对象 a2 ,除 a1 中的参考字段外,还有其他引用。

4 个答案:

答案 0 :(得分:5)

垃圾收集器理想地收集程序流无法访问的所有对象。即使此对象引用了JVM中的所有内容 如果程序的所有正在运行的线程都不包含任何直接间接引用,则对象将无法访问。
直接引用如下所示:

void main(String... args){
  Object a = new Object(); // <- from here main thread of program 
                           //    has reference to object `a`
  ...
}

间接引用如下所示:

void main(String... args){
   List b = new ArrayList();
   b.add(new Object()); // <- here you can't access object by typing `a`
   // as in previous example, but you can get access with `b.get(0);`
   // so that object can be accessed indirectly -> it is reachable.
}

它还可以正确处理大块对象的情况,这些对象相互引用,但不再能从程序流中访问它们。

MyClass a = new MyClass();
MyClass b = new MyClass();
a.field = b;
b.field = a;
// at this point a and b are reachable so they cannot be collected
b = null;
// at this point b's object is reachable indirectly through `a.field`
// so neither a nor b can be collected
a = null;
// at this point you cannot reach neither a nor b
// so a and b can be garbage collected, 
// despite the fact that a is referenced by b and vice versa

UPD:添加了一些示例,更改了一些单词以使答案更清晰。

答案 1 :(得分:1)

即使其字段仍引用其他对象,也可以收集对象a1。您不需要将其字段设置为null。

垃圾收集器收集不可访问的对象。对象可以保存对其他人的引用,但仍然可以收集。对象可以从其他不可到达的对象引用它,并且仍然可以被收集。

答案 2 :(得分:0)

所有孤立对象都自动符合垃圾回收的条件。而且你不需要将引用设置引用为null(但这是一个很好的编码实践)。

答案 3 :(得分:0)

当垃圾收集器运行时,它会看到现在a1需要进行垃圾收集,因为不再引用它。

此外,它还会删除指向a1

对象的a2中的引用字段

但仍适用于a2(正如您在a2 中所提到的那样,除了a1 中的引用字段外,还有其它引用)因此它不符合垃圾回收的条件因此它仍然存在。