【问题标题】:Failing to save or close resource created and giving memory leak issue无法保存或关闭创建的资源并出现内存泄漏问题
【发布时间】:2019-08-09 13:40:36
【问题描述】:

我在下面的 C# 代码中遇到了内存泄漏问题,这是什么意思以及如何解决它。我已经在使用using 块了。

未能保存或关闭由 new System.Management.ManagementObjectSearcher("select DeviceID, Model from Win32_DiskDrive where InterfaceType = 'USB'") 创建的资源会泄漏它

using (var managementObjectSearcher = new ManagementObjectSearcher("select DeviceID, Model from Win32_DiskDrive where InterfaceType = 'USB'").Get())
        {
           foreach (var drive in managementObjectSearcher){}

        }

【问题讨论】:

  • 你知道类的dispose 方法中有什么返回类型为ManagementObjectSearcher("").Get() 吗?
  • 您是否尝试过将 .Get() 方法移至 foreach 语句?(foreach (var drive in managementObjectSearcher).Get())
  • 你怎么断定这是内存泄漏?根据接受的答案,Finalization 仍然会被触发

标签: c# memory-leaks


【解决方案1】:

你没有处理ManagementObjectSearcher;您正在处理 Get 方法调用的结果。试试这个:

using (var managementObjectSearcher = new ManagementObjectSearcher(
             "select DeviceID, Model from Win32_DiskDrive where InterfaceType = 'USB'"))
using (var collection = managementObjectSearcher.Get())
{
  ...
}

【讨论】:

  • 非常好,非常感谢。
  • 为什么这会导致内存泄漏,Finalization 仍然会触发,本质上 OP 正在查看的是由于没有调用显式 Dispose 而导致的内存峰值或线性增加
  • @MrinalKamboj 终结器所做的是实现细节。 IDisposable 的合同明确规定实现 IDisposable 的对象 必须 显式处置,所以这就是你应该做的。总是有 X509Store(以及其他处理 X509 证书的类)的示例,尽管它们是绝对必要的,但它们没有终结器(遗憾的是,它们甚至没有实现 IDisposable)。如果您应该调用 dispose 方法,请调用它。不要依赖终结器。无法保证它们会运行。
  • @Luaan 感谢您提供的详细信息,我理解您的观点,但是没有办法处理开发人员总是调用 dispose,这只是一个建议,就 Finalization 而言,GC 必然会调用它,如果没有明确禁止,您提到的情况非常具体。对我来说,更大的挑战是 OP 称之为内存泄漏,在我看来这是不正确的,最多会是内存的峰值,直到最终确定开始
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多