ガベージコレクターは、ファイナライザーがそのオブジェクトで実行されるのを待ってから収集しますか?
あなたの質問は少し曖昧です。
GCは、ファイナライズが必要な「デッド」オブジェクトに遭遇すると、デッドオブジェクトのストレージを再利用する試みを中止します。代わりに、オブジェクトを「ファイナライズが必要であることがわかっているオブジェクト」のキューに入れ、ファイナライザースレッドが完了するまで、そのオブジェクトを有効なものとして扱います。
したがって、はい、GCはファイナライザーが実行されるまで「待機」してからストレージを再利用します。ただし、同期的に待機しません。「GCはファイナライザーを同期的に呼び出しますか?」と質問しているようです。いいえ、後でファイナライズするオブジェクトをキューに入れ、トラックインを続けます。GCは、適切なプログラムができるだけ早く実行を再開できるように、ガベージを解放してメモリを圧縮するタスクを迅速に実行したいと考えています。クリーンアップされる前に注意を必要としている気まぐれなオブジェクトを処理するのをやめるつもりはありません。そのオブジェクトをキューに入れ、「静かにして、ファイナライザースレッドが後で処理します」と表示します。
後でGCはオブジェクトを再度チェックし、「まだ死んでいますか?そしてファイナライザーを実行しましたか?」と言います。答えが「はい」の場合、オブジェクトは再利用されます。(ファイナライザーは、死んだオブジェクトをライブのオブジェクトに戻す可能性があることを忘れないでください。決してそうしないようにしてください。結果として、楽しいことは何も起こりません。)
ファイナライザーの実行中にスレッドの一時停止を解除しますか?
GCは、フリーズしたスレッドを解凍し、ファイナライザースレッドに「やらなければならない作業があります」と通知すると思います。したがって、ファイナライザスレッドが実行を開始すると、GCによってフリーズされたスレッドが再び起動します。
ファイナライザーは、スレッドに関連付けられたリソースを解放するために、ユーザースレッドへの呼び出しをマーシャリングする必要がある場合があるため、フリーズされていないスレッドが必要になる場合があります。もちろん、これらのユーザースレッドの一部はブロックまたはフリーズされる可能性があります。スレッドは常に何かによってブロックされる可能性があります。
ファイナライザーが中断されたスレッドの1つによって保持されているロックに遭遇した場合はどうなりますか?ファイナライザースレッドはデッドロックしますか?
もちろんです。ファイナライザースレッドには、デッドロックを防ぐ魔法はありません。ユーザースレッドがファイナライザースレッドによって取得されたロックを待機していて、ファイナライザースレッドがユーザースレッドによって取得されたロックを待機している場合、デッドロックが発生しています。
ファイナライザースレッドのデッドロックの例はたくさんあります。他のシナリオへのリンクがたくさんある、そのようなシナリオの1つに関する優れた記事を次に示します。
http://blogs.microsoft.co.il/blogs/sasha/archive/2010/06/30/sta-objects-and-the-finalizer-thread-tale-of-a-deadlock.aspx
記事にあるように、ファイナライザーは非常に複雑で危険なクリーンアップメカニズムであり、可能であれば回避する必要があります。ファイナライザーを間違えるのは信じられないほど簡単で、正しくするのは非常に困難です。