是否有必要对每个 ManagementObject 进行处理? [英] Is it necessary to dispose every ManagementObject?

查看:28
本文介绍了是否有必要对每个 ManagementObject 进行处理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到 ManagementObjectIDisposable,但它也是从 ManagementClass.GetInstances()ManagementObjectSearcher.Get() 返回的,这是否意味着我需要处理遇到的每个对象?

I noticed that ManagementObject is IDisposable, but it's also returned from ManagementClass.GetInstances() and ManagementObjectSearcher.Get(), does this mean I need to dispose each object encountered?

像这样:

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

进一步混淆这一点:ManagementBaseObject 中存在一个错误,它没有正确实现 IDisposable(请参阅 Using 子句无法调用 Dispose? ) 所以你需要自己调用它,或者使用一个可以正确调用它的包装器.

Further confounding this: there's a bug in ManagementBaseObject where it does not correctly implement IDisposable (See Using clause fails to call Dispose? ) so you need to call it yourself, or use a wrapper around it that does correctly call it.

这很烦人,因为我周围有很多 ManagementObjectCollections.

This is irritating because I have so many ManagementObjectCollections around.

推荐答案

这很烦人,因为我周围有很多 ManagementObjectCollections.

This is irritating because I have so many ManagementObjectCollections around.

这与调用 Dispose() 无关,它只会释放底层的非托管 COM 对象.ManagementObjectCollection 是一个托管类,它的实例被垃圾收集.这是自动的,您只能通过调用 GC.Collect() 来提供帮助.您的程序可能只是创建了很多 System.Management 对象,可能是因为这是它所做的唯一一件事.引用的错误已在我安装在我的机器上的当前版本的 .NET 3.5SP1 和 .NET 4.5 中修复.

Which has nothing to do with calling Dispose(), that only releases the underlying unmanaged COM objects. ManagementObjectCollection is a managed class, instances of it are garbage collected. Which is automatic, you can only help by calling GC.Collect(). Your program is probably just creating a lot of System.Management objects, possibly because that's the only thing it ever does. The quoted bug was fixed in the current versions of .NET 3.5SP1 and .NET 4.5 that I have installed on my machine.

因此,如果您没有 .NET 的修补版本,那么您不仅会在 GC 堆上看到大量 System.Management 对象,您的进程还将消耗大量非托管内存.如果垃圾收集器运行不够频繁,则可能导致程序因 OOM 而崩溃.您没有将其作为故障模式提及,因此并不能强烈表明您遇到了真正的问题.

So if you don't have a patched version of .NET then you don't only see a lot of System.Management objects on the GC heap, your process will also consume a lot of unmanaged memory. If the garbage collector doesn't run frequently enough then that can cause the program to crash with OOM. You didn't mention that as a failure mode so it is not strongly indicated that you have a real problem.

GC 堆的第 0 代初始大小为 2 兆字节,它可以增长到 8 兆字节以上.这是一个很多的 ManagementObjectCollections 对象,它是一个非常小的对象,在 32 位模式下仅占用 24 个字节.实际的集合是不受管理的.使用 Perfmon.exe 或您的内存分析器检查垃圾收集器是否足够频繁地运行.如果没有,那么请注意您的程序的 VM 大小.如果这是膨胀,那么在查询循环中使用计数器并在它足够高时调用 GC.Collect() 是一个可行的解决方法.小心你从内存分析器中得到的信息,它可能会因为错误的原因而恼火.

The initial size of generation 0 of the GC heap is 2 megabytes, it can grow to 8+ megabytes. That is a lot of ManagementObjectCollections objects, it is a very small object that takes only 24 bytes in 32-bit mode. The actual collection is unmanaged. Use Perfmon.exe or your memory profiler to check that the garbage collector is running frequently enough. If it doesn't then keep an eye on your program's VM size. If that's ballooning then using a counter in your query loop and calling GC.Collect() when it is high enough is a viable workaround. Careful with the info you get out of a memory profiler, it can irritate for the wrong reasons.

这篇关于是否有必要对每个 ManagementObject 进行处理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆