1

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

如果我的描述不清楚,我会尝试概括(或简化)我的问题。假设类A的对象a1具有一个字段,该字段引用同一类的另一个对象a2。如果没有对对象a1的引用,它是否符合垃圾收集器的条件?或者我们必须将a1中的引用字段显式设置为null?(不要关心对象a2 ,除了a1中的引用字段之外,还有其他对它的引用)。

4

4 回答 4

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:添加示例,更改了一些单词以使答案更清晰。

于 2013-04-02T13:10:43.373 回答
1

您的对象 a1 可以被收集,即使它的字段仍然引用其他对象。您不需要将其字段设置为空。

垃圾收集器收集不可到达的对象。一个对象可以保存对其他对象的引用,并且仍然可以被收集。一个对象可能有对它的引用,来自其他不可访问的对象,并且仍然被收集。

于 2013-04-02T13:33:49.800 回答
0

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

于 2013-04-02T13:13:22.590 回答
0

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

它还将删除a1指向对象的引用字段a2

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

于 2013-04-02T13:17:23.247 回答