0

I have a class (lets call it class a) that contains a "reference class" (lets call it reference class b) which points to "class a".

This create a loop connection, if all other references to "class a" and "reference class b" would be dropped they would still have classes referring to them. Is the Garbage Collection in C# strong enough to detect this internal loop only, or would I need to break that link somehow before they can be collected (once all external links are broken this would be impossible)

See following example code of how the two keeps referencing each other.

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

}

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

Using the above 2 classes if a version of ClassA is made external, and then set to null, there is still a reference to that Object, and likewise with the created ReferenceClassB object. But these objects would not be connected to the "main program", so in theory they are safe for the Garbage Collector to clean, but is the actual implementation smart enough to get rid of them?

Taoh
  • 331
  • 2
  • 12
  • Yes, GC can do this. In C++.NET, there are special classes for this kind of references, but in C# it works. – user35443 Aug 25 '13 at 16:15
  • Thanks both of you, answered my question, and gave me a better understanding of what still might cause issues. In my current implementation it will "delink" from the main program (root) and due to this be collected. – Taoh Aug 25 '13 at 16:20

1 Answers1

2

Yes, Garbage collector handles circular references. check this question on stackoverflow.

UPDATE:

you can Test that by using the following code:

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);
    }
}
Community
  • 1
  • 1
mehdi.loa
  • 579
  • 1
  • 5
  • 23