5

であることに気付きましたManagementObjectが、およびIDisposableからも返されます。これは、遭遇した各オブジェクトを破棄する必要があるということですか?ManagementClass.GetInstances()ManagementObjectSearcher.Get()

そのようです:

ManagementObject ret;
foreach(ManagementObject mo in searcher.Get()) {
    if( IsWhatIWant(mo) ) ret = mo;
    else mo.Dispose();
}

これをさらに混乱させます:ManagementBaseObject正しく実装されていないバグがありますIDisposable( Using 節が Dispose の呼び出しに失敗するを参照してください)。そのため、自分で呼び出すか、正しく呼び出すラッパーを使用する必要があります。

ManagementObjectCollections周りにたくさんいるのでイライラします。

4

4 に答える 4

2

周りに非常に多くの ManagementObjectCollection があるため、これはイライラします。

Dispose() の呼び出しとは関係ありません。これは、基になるアンマネージ COM オブジェクトのみを解放します。ManagementObjectCollection はマネージ クラスであり、そのインスタンスはガベージ コレクトされます。これは自動で、GC.Collect() を呼び出すことによってのみ支援できます。あなたのプログラムはおそらく多くの System.Management オブジェクトを作成しているだけでしょう。引用されたバグは、自分のマシンにインストールした .NET 3.5SP1 および .NET 4.5 の現在のバージョンで修正されました。

したがって、パッチを適用したバージョンの .NET を使用していない場合、GC ヒープ上に多数の System.Management オブジェクトが表示されるだけでなく、プロセスも大量のアンマネージ メモリを消費します。ガベージ コレクターが十分な頻度で実行されないと、プログラムが OOM でクラッシュする可能性があります。あなたはそれを失敗モードとして言及しなかったので、実際の問題があることを強く示していません.

GC ヒープのジェネレーション 0 の初期サイズは 2 メガバイトですが、8 メガバイト以上に拡大できます。これは多数の ManagementObjectCollections オブジェクトであり、32 ビット モードで 24 バイトしか使用しない非常に小さなオブジェクトです。実際のコレクションは管理されていません。Perfmon.exe またはメモリ プロファイラーを使用して、ガベージ コレクターが十分な頻度で実行されていることを確認します。そうでない場合は、プログラムの VM サイズに注意してください。それがバルーニングしている場合は、クエリループでカウンターを使用し、十分に高いときに GC.Collect() を呼び出すことが実行可能な回避策です。メモリ プロファイラから取得した情報には注意してください。誤った理由でイライラする可能性があります。

于 2013-03-29T10:58:47.210 に答える
1

実際のコードは次のとおりです。

http://referencesource.microsoft.com/#System.Management/managementobjectcollection.cs

また、Microsoft Symbol Server のシンボル

http://msdl.microsoft.com/download/symbols

ManagementObjectCollection が IDisposable であることを暗示します。これは、何らかの理由でアンマネージド リソースを使用しているか、IDisposable インターフェイスを誤って使用していることを意味します。

于 2014-09-18T14:13:00.253 に答える