アプリケーションのメモリ使用量を最適化する必要があります。だから私は.netパフォーマンスプロファイラーを使用しました...しかし、私のアプリケーションのいくつかの参照はまだ生きていて、強制的に収集してもGCによって収集されません。
生きている参照は「ファイナライズハンドル」タイプです。この種の参照を削除するために何をすべきかわかりません....助けてください。
アプリケーションのメモリ使用量を最適化する必要があります。だから私は.netパフォーマンスプロファイラーを使用しました...しかし、私のアプリケーションのいくつかの参照はまだ生きていて、強制的に収集してもGCによって収集されません。
生きている参照は「ファイナライズハンドル」タイプです。この種の参照を削除するために何をすべきかわかりません....助けてください。
これはメモリ リークではなく、AMProLibrary の作成者のコードがずさんなだけです。
ご覧のとおり、プロファイラーは、参照されているオブジェクトのタイプが「ファイナライズ ハンドル」であることを示しています。つまり、ファイナライザー キューから来ているということです。ファイナライザー キューは、ファイナライザー メソッドを実装するすべてのオブジェクトを保持するために .NET ガベージ コレクターが使用するものです。ファイナライザーは、ガベージ コレクション中にアンマネージ リソースが適切に解放されるようにするために使用されるメカニズムです。アンマネージ リソースを含むオブジェクトは、アンマネージ リソースが解放されるメソッドIDisposableを含むパターンを実装します。Finalizeガベージ コレクターが「ファイナライズ可能な」オブジェクトを処理するとき (オブジェクトのヘッダーのビットの値で示されます)、それらをファイナライザー キューに移動します。収集中、GC はファイナライザ キューを反復処理し、Finalizeこれらの各オブジェクトのメソッド。
ライブラリの作成者が明らかに失敗したことは、メソッドGC.SuppressFinalize()内から呼び出すことです。Disposeこれは、通常、オブジェクトのヘッダーの「ファイナライズ可能」ビットをクリアすることによってファイナライザー キューからオブジェクトを削除し、Finalizeメソッドを呼び出す必要がないことを示します。
テスト目的で、関数を呼び出してファイナライザーを強制的に実行できGC.WaitForPendingFinalizersます。例えば:
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.GC.Collect();
ただし、実稼働アプリケーションでこのようなコードを実際に使用するべきではありません。コレクションを強制することはほとんど意味がありません。これは、上記の仮説の妥当性を証明するだけです。
一般に、ファイナライザーに依存してアンマネージ リソースを解放するべきではありません。実装するすべてのオブジェクトは、メソッドを手動で呼び出すか、できれば、ブロックのスコープが終了したときに自動的に呼び出されるブロックで作成をラップすることIDisposableにより、コードで明示的に破棄する必要があります。DisposeusingDispose