CLR 徹底解剖: IDisposable について
CLR 徹底解剖 IDisposable について Shawn Farkas
コンテンツ
破棄可能なオブジェクト[=>]

Disposable パターン[=>]

マネージ リソースとネイティブ リソース[=>]

マネージ リソースのクリーンアップ[=>]

Disposable 型からの派生[=>]

Dispose とセキュリティ[=>]

SafeHandles[=>]

まとめ[=>]

共通言語ランタイム (CLR) がマネージ コードの開発者に提供している生産性向上のための機能の 1 つに、マネージ ヒープに割り当てられたメモリが不要になるとガベージ コレクタ (GC) によってクリーンアップされるという機能があります。 これにより、開発者は、メモリのリークや、解放されたメモリを使おうとしたり、メモリを二重解放したりすることによって生じる困難な問題のデバッグに膨大な時間を費やす必要がなくなりました。 しかし、ガベージ コレクタはメモリのリークを防ぐのには有効ですが、解放する必要がある他のリソースについての情報は保持していません。 たとえば、ガベージ コレクタは、ファイル ハンドルを閉じる方法や、CoAllocTaskMem などの API を使用してマネージ ヒープの外部に割り当てられたメモリを解放する方法を知りません。 そのような種類のリソースを管理するオブジェクトは、リソースが不要になったときに確実に解放されるようにする必要があります。 そのためには、System.Object の Finalize メソッドをオーバーライドします。これにより、オブジェクトが自身のクリーンアップを実行しようとしていることをガベージ コレクタに通知できます (C# では、このメソッドを直接オーバーライドするのではなく、C++ のデストラクタ構文である ~MyObject を使用します)。 クラスにファイナライザがある場合、ガベージ コレクタは、その型のオブジェクトを収集する前にオブジェクトのファイナライザを呼び出して、オブジェクトが保持しているすべてのリソースのクリーンアップを実行できるようにします。 このシステムにおける問題の 1 つは、ガベージ コレクタが確定的に実行されないことであり、その結果として、オブジェクトへの最後の参照がなくなった後も長時間にわたってオブジェクトのファイナライズが実行されない可能性があることです。オブジェクトが高価または希少なリソース (データベース接続など) を保持する場合、これは許容できない問題になります。たとえば、利用可能な開いている接続が 10 個しかなく、そのうちの 1 つをオブジェクトが保持している場合、オブジェクトは、ガベージ コレクタがファイナライズ メソッドを呼び出すのを待たずにできるだけ早くその接続を解放する必要があります。
破棄可能なオブジェクト 不確定な期間にわたってガベージ コレクタの実行を待機する必要をなくすには、リソースを所有する型が IDisposable インターフェイスを実装する必要があります。これにより、その型のコンシューマは適切なタイミングでリソースを解放できるようになります。 IDisposable の実装は、オブジェクトの操作が終了した直後に Dispose を呼び出す必要があることをオブジェクトのコンシューマに示し、不要になったリソースをオブジェクトが直ちに解放できるようにします。 C# と Visual Basic® には、このプロセスをできるだけ簡単にするための "using" キーワードが用意されています。 C# では、IDisposable を実装している MyClass クラスがある場合、次のコードによってコンパイラに図 1 のようなコードを生成させることができます。 Figure 1 生成されるコード
MyClass myClass = GetMyClass(); try { myClass.DoSomething(); } finally { IDisposable disposable = myClass as IDisposable; if (disposable != null) disposable.Dispose(); } using (MyClass myClass = GetMyClass()) { myClass.DoSomething(); } try/finally ブロックを使用すると、using ブロック内のコードで例外が発生した場合でも、MyClass の Dispose メソッドはオブジェクトのクリーンアップを確実に実行できます。
Next Page
Full Browser

ja.abc-yoga.podzone.org | Contact