アンマネージ リソースのクリーンアップ

アプリケーションで作成するオブジェクトの大部分については、.NET のガベージ コレクターにメモリ管理を任せることができます。 しかし、アンマネージ リソースを含むオブジェクトを作成する場合は、そのオブジェクトの使用が終了した時点で、そのリソースを明示的に解放する必要があります。 アンマネージ リソースの種類で最も一般的なのは、ファイル、ウィンドウ、ネットワーク接続、データベース接続などのオペレーティング システム リソースをラップしたオブジェクトです。 ガベージ コレクターは、アンマネージ リソースをカプセル化したオブジェクトを有効期間全体にわたって監視できますが、アンマネージ リソースを解放しクリーンアップする方法については情報を持っていません。

型でアンマネージ リソースを使用している場合は、次のようにする必要があります。

  • dispose パターンを実装します。 これは、アンマネージ リソースの確定的解放を有効にするために IDisposable.Dispose の実装を提供する必要があります。 型のコンシューマーはオブジェクト (および使用するリソース) が不要になると Dispose を呼び出します。 Dispose メソッドはアンマネージ リソースを直ちに解放します。

  • 型のコンシューマーが Dispose の呼び出しを忘れた場合のために、アンマネージ リソースを解放する方法を用意します。 これには、2 つの方法があります。

    • アンマネージ リソースをラップするセーフ ハンドルを使用します。 この手法を使用することをお勧めします。 セーフ ハンドルは System.Runtime.InteropServices.SafeHandle 抽象クラスから派生し、堅牢な Finalize メソッドを含みます。 セーフ ハンドルを使用するときは、単純に IDisposable インターフェイスを実装し、Dispose の実装でセーフ ハンドルの IDisposable.Dispose メソッドを呼び出します。 セーフ ハンドルのファイナライザーは、Dispose メソッドが呼び出されなかった場合、ガベージ コレクターによって自動的に呼び出されます。

      または

    • Object.Finalize メソッドをオーバーライドします。 終了処理では、型のコンシューマーが IDisposable.Dispose を呼び出してアンマネージ リソースを確定的に破棄しなかった場合に、リソースを非確定的に解放できます。 Object.Finalize メソッドをオーバーライドすることでファイナライザーを定義します。

    警告

    ただし、オブジェクトの終了処理は複雑でエラーが発生しやすい操作であるため、独自のファイナライザーを用意する代わりに、セーフ ハンドルを使用することをお勧めします。

これで型のコンシューマーは、IDisposable.Dispose の実装を直接呼び出して、アンマネージ リソースで使用されるメモリを解放することができます。 Dispose メソッドを適切に実装すると、セーフ ハンドルの Finalize メソッドまたは Object.Finalize メソッドの独自のオーバーライドは、Dispose メソッドが呼び出されなかった場合にリソースをクリーンアップするための安全装置になります。

このセクションの内容

Dispose メソッドの実装」では、アンマネージ リソースを解放する破棄パターンを実装する方法について説明します。

IDisposable を実装するオブジェクトの使用」では、型のコンシューマーが Dispose の実装を確実に呼び出す方法について説明します。 このためには、C# の using ステートメント (または Visual Basic の Using ステートメント) を使用することをお勧めします。

関連項目

型/メンバー 説明
System.IDisposable アンマネージ リソースの解放のための Dispose メソッドを定義します。
Object.Finalize アンマネージ リソースが Dispose メソッドによって解放されない場合に、オブジェクトの終了処理を提供します。
GC.SuppressFinalize 終了処理を抑制します。 このメソッドは、慣例的に Dispose メソッドから呼び出され、ファイナライザーが実行されないようにします。