10

假设有一个类 A 的对象 a,它持有对 B 类的另一个对象 b 的引用。这是对 b 的唯一引用。所以现在,如果所有对 a 的引用都被删除,那么 a 就准备好进行 GC。这是否意味着 b 也准备好收集垃圾了?因为,虽然 b 有一个引用(在 a 内),但它是不可访问的,因为 a 是不可访问的。

那么这个场景究竟是如何运作的呢?我的意思是垃圾收集的顺序。

4

5 回答 5

13

一旦某个对象无法从根目录访问,它将被收集。有关 GC 根的解释,请参阅此问题

将收集整个子图(如您所述),假设可能无法到达该子图中的任何节点。

Java(和.NET)使用标记和清除垃圾收集来处理这类问题。

基于引用计数的系统(例如 C++ 的std::shared_ptr<T>)在循环依赖仍然无法访问的情况下可能会失败。这对 Java/.NET GC 来说不是问题。

于 2013-07-06T17:19:36.323 回答
1

Java GC 足够聪明,可以收集孤立对象的孤岛,尽管它们可能相互指向。因此,b也有资格进行垃圾收集。这里要注意的一点是,尽管您有对它的引用,但从无法从程序的根目录访问b它的意义上说,它并不存在。

于 2013-07-06T17:22:30.287 回答
0

这取决于GC。可以告诉 JVM 使用不同的 GC,通常使用 3 个 GC(eden、copy、markcompact)。

在任何典型的 GC中,并且在引用您描述的情况时,您所描述的情况都得到了干净的处理,两个 obj 都被收集了。分为两个阶段:首先“a”被注意到并被收集,然后“b”被注意到并被收集。同样:注意的具体方式取决于 GC。

于 2013-07-06T17:26:27.300 回答
0

即使对象在内部相互引用,并且它们没有来自程序的可访问引用,它们也有资格进行 GC。这里有一个很好的解释与图表here

http://www.thejavageek.com/2013/06/22/how-do-objects-become-eligible-for-garbage-collection/

于 2013-07-06T19:05:36.673 回答
-1

这正是 GC 的重点。由于 b 无法从主线程访问,因此它将被垃圾收集。重要的不仅仅是数量。

于 2013-07-06T17:29:59.483 回答