假设有一个A类的对象a,它包含对B类另一个对象b的引用。这是对b的唯一引用。所以现在,如果删除了对a的所有引用,那么就可以使用GC了。这是否意味着b也准备好收集垃圾?因为,虽然b有一个引用(在a内),但它是无法访问的,因为a是无法访问的。
那么这种情况究竟是如何运作的?我的意思是垃圾收集的顺序。
答案 0 :(得分:13)
一旦从根目录无法访问某个对象,就会收集该对象。有关GC根的解释,请参阅this question。
将收集整个子图(如您所述),假设该子图中没有任何节点可以到达。
Java(和.NET)使用标记和扫描垃圾收集来处理这类问题。
基于引用计数的系统(例如C ++&#39; s std::shared_ptr<T>
)可能会因循环依赖关系无法访问而失败。这对Java / .NET GC来说不是问题。
答案 1 :(得分:1)
Java GC非常智能,可以收集孤立对象的孤岛,尽管它们可能指向彼此。因此,b
也有资格进行垃圾回收。这里需要注意的是,尽管您引用了b
,但它不是 live ,因为无法从程序的根目录中找到它。
答案 2 :(得分:0)
这取决于GC。可以告诉JVM使用不同的GC,并且通常使用3个GC作为一个(eden,copy,markcompact)。
在任何典型的GC 和中,在重新计算所描述的情况时,处理干净,两个obj都被收集。在两个阶段中考虑它:首先注意到“a”并收集然后“b”被注意到并收集。再说一次:注意的具体方法取决于GC。
答案 3 :(得分:0)
即使对象在内部相互引用,并且它们没有来自程序的可访问引用,它们也有资格获得GC。这是图表的一个很好的解释
http://www.thejavageek.com/2013/06/22/how-do-objects-become-eligible-for-garbage-collection/
答案 4 :(得分:-1)
这正是GC的重点。由于b无法从主线程访问,因此将进行垃圾回收。重要的不仅仅是计数。