考虑这两个类:
public class A
{
B b;
public A(B b) { this.b = b; }
}
public class B
{
A a;
public B() { this.a = new A(this); }
}
如果我有像上面这样设计的类,这些类的对象会被垃圾收集器(GC)收集吗?
假设我这样做:
void f()
{
B b = new B();
}
在这个方法中,我创建了一个名为
B
的 b
实例,当该方法返回时,b
超出范围,GC 应该能够收集它,但如果它要收集它,它必须首先收集a
,它是B
的成员,而要收集a
,它需要首先收集b
,它是A
的成员。它变成圆形。所以我的问题是:这样的循环引用会阻止 GC 收集对象吗?
WeakReference
类?它的目的是什么?.NET垃圾收集器绝对可以处理循环引用。垃圾收集器如何工作的非常的高级视图是......
这允许很好地收集循环引用。只要它们都无法从已知不可收集的对象访问,那么循环引用本质上是无关紧要的。
注意:我意识到为了让这个答案简单直接,我遗漏了许多有趣的细节
不,这不会是问题,因为 GC 可以处理循环引用
MSDN 说
如果一组对象包含彼此的引用,但其中没有一个 这些对象 从堆栈或共享变量直接或间接引用,然后是垃圾 集合会自动回收内存。
几个答案已经解释了循环引用不是问题。
至于弱引用——使用它们的原因是缓存。
当 GC 遍历对象依赖树时,他会忽略弱引用。换句话说,如果对对象的唯一引用是弱引用,它将被垃圾收集,但如果在引用创建和尝试使用之间没有垃圾收集,您仍然可以访问该对象。
不会,循环引用不会影响垃圾收集器,它完全能够收集 B 的实例。
垃圾收集器知道超出范围后没有人可以引用 B 的实例,因此,没有人可以使用 B 的实例来间接引用 A。
刚刚发现 GC 在某些情况下处理循环引用并不是那么好......
使用 WeakReference 无论如何都会造成死胡同。
从 C++ 开始,GC 之路崎岖不平。 在 C++ 中,唯一指针和共享指针更加强大。 GC 没问题,但是……嗯……:)