考虑这两个类:
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
的{{1}}实例,当方法返回时,b
超出范围,GC应该能够收集它,但如果要收集它,则必须首先收集b
成为a
的成员,并收集B
,它需要首先收集a
是b
的成员。它变成了圆形。所以我的问题是:这样的循环引用会阻止GC收集对象吗?
WeakReference
课程?它的目的是什么?答案 0 :(得分:84)
.Net垃圾收集器绝对可以处理循环引用。关于垃圾收集器如何工作的非常高级视图是......
这样可以很好地收集循环引用。只要从已知无法收集的对象中找不到它们,那么循环引用基本上是无关紧要的。
注意:我意识到我遗漏了许多有趣的细节,以便让这个答案变得简单直接
答案 1 :(得分:30)
不,这不会有问题,因为GC可以处理循环引用
MSDN说如果一组对象包含彼此的引用,但没有引用 这些对象 直接或间接地从堆栈或共享变量引用,然后是垃圾 集合将自动回收内存。
答案 2 :(得分:5)
没有那个循环引用不会影响垃圾收集器,它将完全能够收集B的实例。
垃圾收集器知道没有人可以在超出范围后引用B的实例,因此,没有人可以使用B的实例来间接引用A.
答案 3 :(得分:5)
已经解释了几个答案,循环引用不是问题。
对于弱引用 - 使用它们的原因是缓存。
当GC遍历对象依赖关系树时,他忽略了弱引用。换句话说,如果对象的唯一引用是弱对象,则它将被垃圾收集,但如果在引用创建和您尝试使用之间没有垃圾收集,您仍然可以访问该对象。