2016-11-19 73 views
2

当C#程序死亡时,类的属性也应以某种形式销毁。C#垃圾静态依赖关系

试想,一类A,与作为A的静态成员,并用实例B类的实例A B为B的静态成员现在

当程序终止,A的静态成员和B需要收集和销毁。现在想象一下,A.a在析构函数中使用来自B.b的信息,而B.b在它的析构函数中使用来自A.a的信息。

在我们销毁/清理A和A.a之前,您会得到一个循环依赖关系,我们需要销毁/清理B和B.b,然后以相反的方式。我试着用下面的代码。 (Console.WriteLine不会因为工作标准输出获取的闭)

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"); 
    } 
} 

现在,我已经跑了这一点,并看到了,在我的情况了Bb得到了Aa破坏之前被销毁,但Bbdone仍然是可以访问由AA甚至在调用析构函数之后。

我的问题是,一个类/对象在被销毁之后仍然可以被使用?而且,C#如何知道内存何时可以被重用/释放,因为即使没有对象的引用,它也不会重用内存。

回答

1

当C#程序死亡时,类的静态属性也应该以某种形式销毁。

如果这些被管理让他们CLR :)


.NET垃圾收集是基于“代”,所以一个对象可能是由第0代收集垃圾收集,但一直没有从内存中完全“毁坏”或“移除”。

请参阅这里:https://www.simple-talk.com/dotnet/.net-framework/understanding-garbage-collection-in-.net/


如果你从C++背景,要记住,“C++的析构函数”等同于IDisposable接口和Dispose()方法,通常在使用块使用。请参阅msdn.microsoft.com/en-us/library/system.idisposable.aspx。你所说的析构函数被称为Finalizer,它不同于C++析构函数。