Work of Artiz Work of Artiz - 20 days ago 5
C# Question

C# garbage static dependencies

When a C# program dies, the

static
properties of classes should also be destroyed in one form or another.

Imagine, a class A, with an instance a as a static member of A and a class B with an instance b as a static member of B

Now when the program terminate, the static members of A and B need to be collected and destroyed. Imagine now that A.a uses information from B.b in the destructor and B.b uses information from A.a in it's destructor.

You'd get a cyclic dependency, before we can destroy/clean A and A.a we need to destroy/clean B and B.b and the other way around. I tried this with the code below. (Console.WriteLine doesn't work since stdout get's closed)

class A
{
private static A a = new A();
public bool done = false;
private A(){}
~A()
{
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
GC.WaitForPendingFinalizers();
System.IO.File.WriteAllText(@"a.txt", "A got destroyed, b:" + (B.getB().done ? "destroyed" : "intact"));
done = true;
}

public static A getA() { return a; }
}

class B
{
private static B b = new B();
public bool done = false;
private B(){}
~B()
{
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
GC.WaitForPendingFinalizers();
System.IO.File.WriteAllText(@"b.txt", "B got destroyed, a:" + (A.getA().done ? "destroyed" : "intact"));
done = true;
}

public static B getB() { return b; }
}

public class Program
{
public static void ensureInstances() {A.getA(); B.getB();}

public static void Main(string[] args)
{
ensureInstances();
Console.WriteLine("Time to die");
}
}


Now I've ran this and saw that, in my case B.b gets destroyed before A.a is destroyed, but B.b.done is still accessible from A.a even after it's destructor is called.

My question then, how can an class/object still be used after being destroyed ? And how does C# know when the memory can be re-used / freed, since it didn't re-use the memory even though there were no references to the object any more.

Answer

When a C# program dies, the static properties of classes should also be destroyed in one form or another.

If those are managed leave them to CLR :)


.NET Garbage Collection is "generation" based, so an object might be garbage collected by a Generation 0 collection, but has not been completely "destroyed" or "removed" from memory.

Kindly refer here:https://www.simple-talk.com/dotnet/.net-framework/understanding-garbage-collection-in-.net/


If you are from C++ background, bear in mind that "C++ destructor" is equivalent to IDisposable and the Dispose() method, often used in a using block. Please refere to msdn.microsoft.com/en-us/library/system.idisposable.aspx. What you refer as a destructor is known as a Finalizer, and it's different from a C++ destructor.