ガベージ コレクション: GC は、オブジェクトが参照されなくなったときに、オブジェクトが使用していたメモリを回収します。
Dispose : IDisposable インターフェイスのメソッドで、プログラマーが (直接または using ブロックを介して間接的に) 呼び出したときにすべてのマネージ リソースとアンマネージ リソースを解放します。
Finalizer : 管理されていないすべてのリソースを解放する方法。メモリを再利用する前に GC によって呼び出されます。
マネージド リソースIDisposable
: Streams や DbConnections など、インターフェイスを実装する任意の .NET クラス。
管理されていないリソース: 管理されたリソース クラスにラップされたスタッフィング。Windows ハンドルは、最も単純な例です。
あなたの質問に答えるために:
GC は、そのクラスがファイナライザー (C# では ~ClassName) を宣言するすべてのオブジェクトのリスト (ファイナライズ キュー) を保持します。オブジェクトは、作成時にこのキューに入れられます。GC は定期的に実行され、プログラムからアクセスできないオブジェクトがないかどうかを確認します。次に、アクセスできないオブジェクトのいずれかが Finalization Queue から参照されているかどうかをチェックし、これらを Freacheable キューと呼ばれる別のキューに入れ、残りは回収されます。Freacheable キュー内のオブジェクトの Finalize メソッドを実行するために、別のスレッドが使用されます。
次回 GC を実行すると、以前に Freacheable キューにあったオブジェクトの一部が既にファイナライズされているため、再利用の準備ができていることがわかります。Finalizer を使用してオブジェクトを削除するには、GC が少なくとも 2 サイクル (多くの Finalization を実行する場合はそれ以上) を必要とすることに注意してください。これにより、パフォーマンスが低下します。
このSuppressFinalize
メソッドは、Finalizer を実行する必要がないことを示すフラグをオブジェクト ヘッダーに設定するだけです。このようにして、GC はオブジェクトのメモリをすぐに再利用できます。上記の定義に従って、このDispose
メソッドは Finalizer と同じこと (およびそれ以上) を行うため、実行された場合、Finalization は不要になります。このSuppressFinalize
メソッドを使用すると、GC にこの事実を通知することで、GC の作業を節約できます。さらに、二重リリースを回避するためにファイナライザーにチェックを実装する必要がなくなりました。唯一の問題Dispose
は、それを呼び出すのはプログラマーの責任であるため、実行が保証されていないことです。そのため、ファイナライザーを気にする必要がある場合があります。
そうは言っても、ファイナライザを記述する必要があることは非常にまれです。これは、通常のアンマネージ リソースの大部分にはマネージ ラッパーがすでに存在し、マネージ リソースはDispose
独自のメソッドからメソッドをDispose
呼び出すことによって解放されるためです。そしてそこからのみ!ファイナライザーでは、Dispose メソッドを呼び出してはなりません。
さらに読む: