2009-07-19 10 views
0

Fooのクラスでデストラクタを実装すると、Fooのインスタンスがファイナライゼーションキューで密接に追跡されます。 Fooのインスタンスがガベージコレクトされると、CLRはファイナライズキュー内のエントリを見て、そのオブジェクトをヒープの外に移動して到達可能なテーブルに移動させることによってそのオブジェクトに特別な処理を与えます。それでは...ガベージコレクションのサイクルで何も起こらないのですか?ファイナライゼーションの到達可能テーブル

finalize()は常に次のガベージコレクションサイクル中に呼び出されますか?

なぜオブジェクトがフリーチャテーブルにコピーされた直後にfinalizeが呼び出されないのですか? (これは余分な不要な複雑さのようです)

答えて

1

ファイナライザキューは事を単純化するためのものです。それがなければもっと複雑になるだろう。 GCが実行されるとき、マネージコードは実行されません。そうでなければ、ユーザーコードが途中で実行されると、GCが行ったすべての分析が無効になることがあります。

GCが実行されると、すぐに実行されるのではなく、ファイナライズを延期する必要があります。別のスレッドで実行すると、VMがすべてのスレッドに排他的にアクセスする必要がある時間が最小限に抑えられ、同時に実行される可能性が高くなります。

+0

。しかし、ガベージコレクタは、サイクルが終了すると、なぜFinalize()スレッドを起動しないのでしょうか?なぜ次のサイクルを待つのですか? –

+0

なぜそれはそうしないと思いますか?オブジェクトがファイナライズ可能であるが到達不可能な場合、オブジェクトは解放可能キューに追加されます。そこでは、ファイナライザスレッドは、ガベージコレクションが終了した直後にそれを取得します。 –

+0

Andrew Troelsenは次のように指摘しています。「別のスレッドが生成され、次のガーベッジコレクションの各オブジェクトのFinalize()メソッドが呼び出されます。これを考えると、少なくとも2つのガベージコレクションが必要です。オブジェクト "(p191 - Pro C#with .NET 3.0) –