C#中的垃圾收集能否只查找和删除内部链接类?

时间:2013-08-25 16:11:36

标签: c# garbage-collection

我有一个类(让我们称之为类a),它包含一个“引用类”(让我们称之为引用类b),它指向“类a”。

这创建了一个循环连接,如果对“class a”和“reference class b”的所有其他引用都将被删除,那么它们仍然会有引用它们的类。 C#中的垃圾收集是否足够强大,只能检测到这个内部循环,或者我需要以某种方式断开该链接才能收集它们(一旦所有外部链接被破坏,这将是不可能的)

请参阅以下示例代码,了解两者如何相互引用。

Public Class ClassA
{
    Private ReferenceClassB reference;
    Public ClassA()
    {
        reference = new ReferenceClassB(this);
    }

}

Public Class ReferenceClassB
{
    Private ClassA referencedClass;
    Public ReferenceClassB(ClassA reference)
    {
        referencedClass = reference;
    }
}

如果将ClassA的版本设置为外部,然后设置为null,则使用上述2个类,仍然存在对该Object的引用,并且同样使用创建的ReferenceClassB对象。但是这些对象不会连接到“主程序”,所以理论上它们对于垃圾收集器来说是安全的,但是实际的实现是否足够智能去除它们?

1 个答案:

答案 0 :(得分:2)

是的,垃圾收集器处理循环引用。在stackoverflow上检查此question

<强>更新

您可以使用以下代码对其进行测试:

public class ClassA
{
    private ReferenceClassB reference;
    public ClassA()
    {
        reference = new ReferenceClassB(this);
    }

}

public class ReferenceClassB
{
    private ClassA referencedClass;
    public ReferenceClassB(ClassA reference)
    {
        referencedClass = reference;
    }
}
class Program
{
    static void Main(string[] args)
    {
        ClassA a = new ClassA();
        ReferenceClassB b = (ReferenceClassB) a.GetType().GetField("reference", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(a);
        WeakReference weakA = new WeakReference(a);
        WeakReference weakB = new WeakReference(b);
        a = null;
        b = null;
        GC.Collect();
        Debug.Assert(weakA.IsAlive==false);
        Debug.Assert(weakB.IsAlive==false);
    }
}