2009-03-03 11 views
2

私は、次のコードを持っている:私は私のファイナライザメソッドはそうではありませんGC.Collect、に私の呼び出し時に呼び出されるだろうと思ったこの単純なシナリオで、私の.netデストラクタが呼び出されないのはなぜですか?

public class A 
    { 
     ~A() 
     { 
      Console.WriteLine("destructor"); 
     } 
    } 

public static A Aref; 
static void Main(string[] args) 
    { 
     Aref = new A(); 
     int gen = GC.GetGeneration(Aref); 
     Aref = null; 
     GC.Collect(gen, GCCollectionMode.Forced); 
     Console.WriteLine("GC done"); 

    } 

を。

誰でも私の理由を説明できますか?

答えて

13

ファイナライザは、GC.Collect()が返される前に呼び出されません。ファイナライザは別のスレッドで実行されます。GC.WaitForPendingFinalizers()を呼び出すことでそれらを待つことができます。

6

ファイナライザは、例のコレクション中に呼び出されません。ファイナライザは、依然としてファイナライズ可能なキューによってルートされているためです。ただし、ファイナライズが予定されています。つまり、次のガベージコレクション中に収集されます。

ファイナライザ付きの型のインスタンスを収集する場合は、このような2つのコレクションを行う必要があります。

GC.Collect(); 
GC.WaitForPendingFinalizers(); 
GC.Collect(); 

しかし、一般的にはCollect()メソッドを自分で呼び出すべきではありません。

+0

はなぜ二収集が必要とされていますか? – Mark13426

+0

ファイナライザを実行して適格となったオブジェクトを収集します。 a型にはファイナライザがあり、ファイナライザが実行されるか抑制されるまで、インスタンスはファイナライザキューによってルートされます。 –

-1

(それはその時点で収集されている世代であることができなかったとして)あなたが収集するためにGCを求める場合であっても、この特定のオブジェクトが破壊されることが不明である

+0

この簡単な例では、OPは関連する世代が収集されることを確認します。したがって、Collect()を明示的に呼び出す前にコレクションが存在しない限り、期待どおりに動作するはずです。 –

関連する問題