这是一个面试问题,但我不太确定正确答案。假设我们有一些类:
public class A {
public Object link;
public A() {
link = null;
}
}
然后我们创建两个实例:
A a1 = new A();
A a2 = new A();
a1.link = a2;
a2.link = a1;
然后我们发布参考文献:
a1 = null;
a2 = null;
然后问题是:因为JVM会使用GC机制。它将如何处理这种情况?它会在运行时立即删除这两个实例,还是仅仅签署了内存空间并让它们独自存在?如果我有100万个这样的实例形成一个循环但没有外部引用怎么办?清洁会使GC线程挂起吗?
答案 0 :(得分:3)
对象本身可以根据需要使用尽可能多的链接(您提到的一百万个周期)来引用彼此。如果没有“路由”回到某个线程,则无论它们连接多少个符合垃圾的节点,这些对象都有资格进行垃圾回收。
现在这并不意味着他们会被收集,只是他们有资格获得。因此,如果您的垃圾收集器决定不处理它们,那么我认为这可能被视为内存泄漏。你不能保证它们会消失。
答案 1 :(得分:2)
循环引用可能会导致内存泄漏,导致某些垃圾收集策略(如reference counting)的初始实现。 (这并不是说引用计数是天真的,但糟糕的实现可能会遇到问题。)
然而,这个问题对于实施GC的人来说是众所周知的,可以避免。此外,大多数现代JVM使用通常不会遇到此类问题的分代垃圾收集器。
答案 2 :(得分:0)
根据代码的当前逻辑,a1具有指向a2的成员变量,而a2具有指向a1的ha成员变量。当你执行a1 = null时,a1有资格获得GCed。与a2的情况相同。现在当GC运行时,它会尝试查看从root开始可以访问的所有对象,即使这两个相互引用,它们也会在从root开始的链中变得无法访问(隔离的情况)因此它们会收集垃圾而没有任何问题。