うーん、ここに描かれている絵は少しバラ色が強すぎます。ファイナライザーは、.NET での実行も保証されていません。典型的な事故は、ファイナライザー スレッドで例外またはタイムアウト (2 秒) をスローするファイナライザーです。
これは、Microsoft が SQL Server で .NET ホスティング サポートを提供することを決定したときの問題でした。リソース リークを解決するためにアプリを再起動するようなアプリケーションは、実行可能な回避策とは見なされません。.NET 2.0 では、CriticalFinalizerObject クラスから派生することで有効になる重要なファイナライザーが取得されました。このようなクラスのファイナライザーは、制約付き実行領域 (CER) の規則に従う必要があります。これは、本質的に例外が抑制されるコードの領域です。CER でできることは非常に限られています。
元の質問に戻りますが、メモリ以外のオペレーティング システム リソースを解放するには、ファイナライザーが必要です。ガベージ コレクターはメモリを適切に管理しますが、ペン、ブラシ、ファイル、ソケット、ウィンドウ、パイプなどを解放するために何もしません。それ。ファイナライザーは、プログラムがそうするのを忘れた場合でも、それが確実に行われるようにします。自分でファイナライザーを使用してクラスを作成することはほとんどありません。操作リソースはフレームワーク内のクラスによってラップされます。
.NET フレームワークには、そのようなリソースが確実に早期にリリースされるようにするためのプログラミング パターンもあるため、ファイナライザーが実行されるまでリソースが残りません。ファイナライザーを持つすべてのクラスは IDisposable.Dispose() メソッドも実装するため、コードでリソースを明示的に解放できます。これは .NET プログラマーによって忘れられることがよくありますが、ファイナライザーによって最終的に行われることが保証されるため、通常は問題が発生することはありません。多くの .NET プログラマーは、すべての Dispose() 呼び出しが処理されているかどうかを心配して何時間も眠れず、フォーラムでそれに関する膨大な数のスレッドが開始されています。Java 関係者はもっと幸せになれるはずです。
コメントのフォローアップ: ファイナライザー スレッドの例外とタイムアウトは、心配する必要はありません。まず、ファイナライザーを作成していることに気付いたら、深呼吸して、自分が正しい道を進んでいるかどうかを自問してください。ファイナライザーはフレームワーク クラス用です。そのようなクラスを使用して操作リソースを使用する必要があります。そのクラスにファイナライザーを無料で組み込むことができます。SafeHandle クラスに至るまで、重要なファイナライザーがあります。
第 2 に、ファイナライザー スレッドの障害は、全体的なプログラムの障害です。OutOfMemory 例外を取得したり、電源コードにつまずいてマシンのプラグを抜いたりするのと同様です。コードのバグを修正するか、ケーブルを再配線する以外に、それらについてできることは何もありません。Microsoft が重要なファイナライザーを設計することは重要でした。Microsoft は、SQL Server の .NET コードを作成するすべてのプログラマーがそのコードを正しく作成できるとは限りません。自分でファイナライザーをいじっても、そのような責任はありません。Microsoft ではなく、顧客から電話を受けるのはあなたです。