IDisposable を理解しようとする際に、ほとんどの回答で明示的に述べられていないいくつかの質問があります。
オブジェクトに対して dispose を呼び出すと、その時点でオブジェクトが破棄されますか、それともクリーンアップしたいクラス メンバーだけが破棄され、オブジェクト全体が後で GC によって破棄されます。
dispose メソッドでファイナライザーを抑制した後でも、GC は dispose でクリーンアップしなかったすべてのクラス メンバーをクリーンアップしますか?
IDisposable を理解しようとする際に、ほとんどの回答で明示的に述べられていないいくつかの質問があります。
オブジェクトに対して dispose を呼び出すと、その時点でオブジェクトが破棄されますか、それともクリーンアップしたいクラス メンバーだけが破棄され、オブジェクト全体が後で GC によって破棄されます。
dispose メソッドでファイナライザーを抑制した後でも、GC は dispose でクリーンアップしなかったすべてのクラス メンバーをクリーンアップしますか?
オブジェクトへのすべての参照がなくなると、非決定的な方法でオブジェクトがガベージ コレクションされます。 MSDN のガベージ コレクション:ガベージ コレクションの基礎
ガベージ コレクションは、次の条件のいずれかに該当する場合に発生します。
- システムの物理メモリが不足しています。
- マネージ ヒープ上の割り当てられたオブジェクトによって使用されるメモリが、許容可能なしきい値を超えています。これは、マネージ ヒープで許容可能なメモリ使用量のしきい値を超えたことを意味します。このしきい値は、プロセスの実行中に継続的に調整されます。
GC.Collect メソッドが呼び出されます。ほとんどの場合、ガベージ コレクタは継続的に実行されるため、このメソッドを呼び出す必要はありません。この方法は、主に固有の状況とテストに使用されます。
まず最初に、このトピックに関する重複した質問がたくさんあります。本当に他の答えがあなたの質問に明確に答えていない場合、ここにありますが、これは重複として閉じられることを期待しています。
まず、Dispose
これは単なる方法であり、通常の方法です。ガベージコレクションは一切扱っていません。
では、Disposeは何をしますか?これは、ファイルハンドル、ウィンドウハンドルなど、管理されていないリソースをクリーンアップするために使用する必要があります。.NETガベージコレクターが認識していないこと。
したがって、質問1に答えるには、「はい」と言います。オブジェクトを呼び出すDispose
と、そのオブジェクトはその場で破棄されます。後でクリーンアップすることを示すマークがクラスに設定されていません。
Disposeはガベージコレクションを処理しないため、オブジェクトを破棄した後もオブジェクトへの参照を簡単に保持でき、ガベージコレクションは発生しません。ガベージコレクションは、オブジェクトへの参照がなくなった場合にのみ発生します。これは、オブジェクトを呼び出していない場合でも発生する可能性がありますが、オブジェクトを呼び出しているためDispose
発生しません。Dispose
2番目の質問:ファイナライザーサイクルを通過した後にGCがオブジェクトを収集すると、GCは、オブジェクトと、オブジェクトからの参照以外に参照が残っていない参照オブジェクトをクリーンアップします。これはある時点で発生しますが、必ずしも一度に発生するわけではありません。
ファイナライザーを抑制することは、GCが必要以上の作業を行わないようにすることです。「このオブジェクトを見つけて、収集に適格であると判断したら、先に進んで収集します。私はファイナライズを処理しました。 「クリーンアップする必要がないように」。
まず、最も重要なことは、オブジェクトの破棄とオブジェクトのガベージ コレクションはまったく別のものであることを理解する必要があることです。この 2 つを混同しないように注意してください。
オブジェクトで dispose を呼び出すと、メソッドが呼び出されるだけです。Dispose
その後、Dispose
メソッドが を呼び出すGC.SuppressFinalize
可能性がありますが、まったく何もしない可能性があります。完全に実装次第です。
呼び出すと、オブジェクトが収集されたときに GC がオブジェクトのファイナライザーを呼び出さないように要求することだけが発生します (GC.SuppressFinalize
あたかも最初からオブジェクトにファイナライザーがなかったかのように)。
IDisposable
たまたま、アンマネージ リソースを決定論的にクリーンアップできるように、ファイナライザーも実装するオブジェクトの一般的なパターンがあります。ファイナライザーは、Dispose
呼び出したときに既に実行されていGC.SuppressFinalize
ます。呼び出しは、最終的にファイナライザーを実際に呼び出す必要がないことを GC にわかりやすく示すためのものです。
1)オブジェクトに対してdisposeを呼び出すと、Dispose()メソッドのコードが実行されるだけです。もちろん、このコードは1つ以上のフィールドに対してDispose()を呼び出すことができますが、必須ではありません。
Dispose(true)
基本クラスを(経由で)呼び出すこともできますが、これbase.Dispose()
はDisposeIdiomを使用しています。インターフェイスDispose(bool)
の一部ではありません。IDisposable
2)ファイナライザーは、SuppressFinalize()が呼び出された特定のオブジェクトに対してのみ抑制されます。他のオブジェクト(SuppressFinalize()が呼び出されたオブジェクトのフィールドによって保持されているものを含む)には影響しません。