IDisposableの実装方法に関するMSDNの記事を読んでいましたが、記事で引用されているマネージドリソースとネイティブリソースの違いについてはよくわかりません。
破棄するときに2つのフィールドを破棄する必要があるクラスがあります。それらをマネージド(破棄= trueの場合にのみ破棄)またはネイティブリソースとして扱う必要がありますか?
IDisposableの実装方法に関するMSDNの記事を読んでいましたが、記事で引用されているマネージドリソースとネイティブリソースの違いについてはよくわかりません。
破棄するときに2つのフィールドを破棄する必要があるクラスがあります。それらをマネージド(破棄= trueの場合にのみ破棄)またはネイティブリソースとして扱う必要がありますか?
ブライアンの答えとあなたのコメント/質問に少し追加するには:
マネージド リソースとアンマネージド リソースの違いは、ガベージ コレクターがマネージド リソースを認識し、アンマネージド リソースを認識しないことです。答えはあまり具体的ではないことはわかっていますが、違いは非常に大きいです。
ここで砂に線を引くのを助けるために、GC がどのように実行され、メモリをクリーンアップするかの短い (そしておそらくほとんどエラーがなくて困惑している) バージョンがあります。
ガベージ コレクターはすべての管理対象オブジェクトを認識していますが、ガベージ コレクションの実行時には、特定のオブジェクトがまだ使用されているかどうか、または解放できるかどうかを最初は認識していません。最初にすべてのオブジェクトをガベージとしてマークし、次にアプリケーション ルートからすべての参照オブジェクトにトラバースすることによって、オブジェクトをクリーンアップできるかどうかを判断します。ルート (直接または間接のいずれかの参照) に戻る関係を持つ各オブジェクトは、到達可能としてマークされ、もはやガベージとは見なされなくなります。GC が到達可能なすべてのオブジェクトを実行した後、それらは使用されなくなったため、残りはクリーンアップされます。
ほとんどすべての場合、.NET フレームワーク オブジェクトを操作すると、オブジェクトが確実に管理されます (.NET は、ほとんどすべてのアンマネージ リソースのマネージド ラッパーを提供して、それらが適切にクリーンアップされるようにします)。Win32 API にフックする他のサード パーティ コンポーネント (またはこれを行うコンポーネント) は、懸念の原因となる可能性があるオブジェクトです。
多少管理されていないと考えられる .NET オブジェクトがいくつかあります。グラフィックス ライブラリのコンポーネントはその一例です。
ほとんどの「.NET メモリ リーク」は、本当の意味でのメモリ リークではありません。通常、オブジェクトを使用から削除したと思われるが、実際にはオブジェクトがまだアプリケーションへの参照を持っている場合に発生します。一般的な例は、イベント ハンドラ (obj.SomeEvent += OnSomeEvent - または - AddHandler obj.SomeEvent, AddressOf OnSomeEvent) を追加し、それらを削除しないことです。
これらの「残留参照」は、技術的にはアプリケーションがまだそれらを使用しているため、技術的にはメモリ リークではありません。ただし、それらが十分にある場合、アプリケーションのパフォーマンスに重大な影響が及ぶ可能性があり、リソースの問題 (OutOfMemoryExceptions、ウィンドウ ハンドルを取得できないなど) の兆候が見られる場合があります。
私は中級の .NET 開発者であり、残念ながらこれらの問題について直接知っています。残りの参照に慣れるのに役立つように ANTS Profiler を試してみることをお勧めします (無料の試用版があります)。または、WinDbg と SOS.DLL を使用してマネージ ヒープを調べるためのもう少し詳細な調査を行いたい場合。後者について調べることにした場合は、Tess Ferrandez のブログを読むことをお勧めします。彼女は、Windbg を効果的に使用するための素晴らしいチュートリアルとアドバイスをたくさん持っています。
管理対象リソースは、を実装する別の管理対象タイプIDisposableです。Dispose()使用する他のIDisposableタイプを呼び出す必要があります。ネイティブリソースは、ネイティブWindowsハンドルなど、管理対象の世界以外のものです。
編集:コメントの質問への回答(コメントには長すぎます)
いいえ、それは単なる管理タイプです。実装されていない正しく構築された型はIDisposable、ガベージコレクターによって処理され、他に何もする必要はありません。タイプがネイティブリソースを直接使用する場合(たとえば、Win32ライブラリを呼び出すことによって)、IDisposableタイプに実装し、Disposeメソッド内のリソースを破棄する必要があります。タイプがを実装する別のタイプによってカプセル化されたネイティブリソースを使用する場合は、タイプのメソッドでこのタイプのインスタンスをIDisposable呼び出す必要があります。Dispose()Dispose
簡単に言えば、CLR の背後で (OS に対して) 取得するものはすべて、「ネイティブ」と呼ぶことができます。
これで、CantStayManaged には、別れを告げる前に片付けなければならないことが 2 つあります。
現在、オブジェクトのクリーンアップをトリガーできる方法は 2 つあります。
どちらの場合も、管理されていないリソースを解放する必要があります。et.all 表面。ただし、管理対象リソースのクリーンアップは、前者の Dispose() の場合にのみ試行する必要があります。後者/ファイナライザーの場合 - CLR は既にメンバーの一部をファイナライズして収集している可能性があるため、それらにアクセスしないでください (CLR はオブジェクト グラフがファイナライズされる順序を保証しません)。if (AmIBeingCalledFromDispose)ガード チェックによるマネージド クリーンアップ
HTH