メソッドに関するいくつかの記事を読んでいて、アンマネージ リソースはメソッド (または finalize() メソッド)Dispose()
から明示的に解放する必要があることがわかりました。その記事には、ファイル ハンドルとデータベース接続オブジェクトはアンマネージ リソースの例であると書かれています。Dispose()
それらが管理されていない理由と、Dispose() で適切に処理されないとどうなるかを誰かが説明できますか? ファイルハンドルとは何かわかりません。それらはどこに存在しますか?
2 に答える
この文脈では、次のように考えるのがおそらく最も簡単です。
Windows Handle
アンマネージ リソースは、ある時点で解放する必要があるを返す Windows API 呼び出しを行うことによって取得した任意のリソースです。他の種類のリソースはメモリだけです。.Net によって割り当てられた場合、これは自動的に管理されます。(Windows API を使用してメモリを割り当てる方法があることに注意してください。これはアンマネージリソースとしてカウントされます。)
たとえば、このFileStream
クラスは Windows API を呼び出してファイルを開きますFileStream
が、ファイル ハンドルは内部的に保持されます。そのファイル ハンドルは、ある時点で解放する必要があるアンマネージ リソースを表します。
FileStream
CreateFile()
バックグラウンドで Windows API 関数を使用します。CreateFile
アンマネージ リソースを表すのは、返されるハンドルです。
これらのハンドルを解放しないと、プログラムの実行中は割り当てられたままになりますが、管理されていないリソースを持つすべての .Net クラスは、ある時点で通常解放されるようにFinalizer
(以下を参照) を提供します。
(ただし、独自のファイル処理クラスを作成していて、ファイル ハンドルをどこでも解放するのを忘れていた場合、ファイルはプログラムが終了するまで開いたままになります。)
通常、このような管理されていないリソースは、次の2 つの場所で解放されます。
Dispose() メソッド。これは、管理されていないリソースを破棄する通常の方法です。
Finalizer
。_ これは最終手段のメカニズムです。クラスにファイナライザーがある場合、デッド オブジェクトをクリーンアップするときにガベージ コレクターによって呼び出されます。管理されていないリソースを持つクラスには、プログラマーが Dispose() の呼び出しを忘れた場合にクリーンアップするためのファイナライザーが必要です。
やや簡略化していますが、理解の助けになれば幸いです。
詳細については、 Dispose パターンに関するこの MSDN の記事を参照してください。
アンマネージ リソースは、Windows API 呼び出しなどに関連していると考える人もいますが、それは実装の詳細です。管理されていないリソースの基本的な特徴は、外部エンティティの側面を表すことです。リソースを所有するオブジェクトの利益のために維持されている状態であり、他のエンティティに損害を与える可能性があり、所有者へのすべての参照が放棄された場合、外部エンティティが維持し続ける-無駄に-状態。外部エンティティは、どこにでもある可能性があることに注意してください。Windows API ハンドルは、可能性の小さなサブセットを表します (ハンドルを取得するオブジェクトは、システムの一部の側面を排他的に使用できるようにすることを Windows に要求し、それらを使用する他のコードに損害を与えます)。外部エンティティが同じアセンブリ内にある (特にリソースがロックまたはイベント サブスクリプションの場合)、または別の大陸にある (リソースがリモート マシン上のファイルの場合) 可能性は十分にあります。
オブジェクトは、その代わりに行動しているエンティティに、その必要がなくなったことを通知することによって、リソースを解放します。マネージド リソースは .NET ヒープ オブジェクトであり、マネージド リソースまたはアンマネージド リソースの組み合わせを所有している可能性がありますが、そのリソースが放棄されると解放される可能性があります。