メモリーリーク。 ManagementBaseObjectはGCルートとして留まりますが、クリーンアップしたことはありません
-
28-09-2019 - |
質問
Ants Memory Profilerを使用して、アプリケーションのメモリ使用量が増え続けている理由を判断しようとしています。
アプリケーションを実行し、時間の経過とともにさまざまなスナップショットを取ります。 iwbemclassObjectFreeThreadedとManagementBaseObjectのライブインスタンスは、時間とともに増加し続けていることがわかります。クラスリファレンスエクスプローラーを見ると、iwbemclassobjectfreeThreadedがmanagementbaseObjectで参照されており、ManagementBaseObjectの100%がGC Rootsであることがわかりますが、クリーンアップされていないようです。他にいつできますか?
解決
これは珍しい問題ですが、起こる可能性があります。 WMIはCOMベースで、IWBEMCLASSOBJECTはRCWラッパーを取得するcomインターフェイスです。これらのラッパーは、ファイナルライザースレッドが実行されるまでクリーンアップされません。技術的には、多くのWMIクエリを実行することは可能ですが、結果とは十分な作業を行いません。
これをPerfmon.exe、パフォーマンスモニターと診断します。グラフを右クリックし、カウンター、.NET CLRメモリを追加し、#GEN 0コレクションカウンターを追加します。下のリストからプログラムを選択します。プログラムが実行されている間、カウンターを観察します。刻々と刻まれていない場合、この問題が発生します。
この場合は、コードを確認し、非常に多くのクエリを実行することが理にかなっているかどうかを確認しますが、結果を使用しないか、まれに使用しないでください。回避策は、それらをカウントすることであり、たとえば100,000回、gc.collect()およびgc.waitforpendingfinalizers()を呼び出します。