【发布时间】:2011-06-11 20:16:33
【问题描述】:
有很多问题询问如何检测 IDisposable 对象泄漏。答案似乎是"you can't"。
我刚刚检查了最简单的测试用例,FxCop 10.0 不这样做,ReSharper 4 with MSVS2010 不这样做。
这对我来说似乎是错误的,比 C 中的内存泄漏更糟糕(至少我们已经建立了检测工具)。
我在想:是否有可能,使用反射和其他模糊的高级技术,我可以在运行时在终结器中注入检查以查看是否已调用 Dispose?
WinDBG+SOS 的魔术怎么样?
即使没有现成的工具可以做到这一点,我想知道这在理论上是否可行(我的 C# 不是很敏锐)。
想法?
注意 此问题的标题可能具有误导性。这里真正的问题应该是IDisposable 对象是否正确地是Disposed()。被 GC 处理掉不算数,因为我认为这是一个错误。
编辑:解决方案:.NET Memory Profiler 完成这项工作。我们只需要在程序结束时向多个GC.Collect() 发送垃圾邮件,以使我们的分析器能够正确获取统计信息。
【问题讨论】:
-
工具存在于 C++ 而可能不存在于 C# 的原因是 C# 中的资源根本不同,因为非托管资源不再与对象生存期耦合。在 C# 和 C++ 中,可以跟踪的是对象生命周期以及对象是否已被正确处理。但是 C# 中的一次性资源并没有以任何方式绑定到对象生命周期,这使得跟踪它们变得更加困难。作为比较,请尝试在 C++ 中跟踪未通过 RAII 绑定到对象生命周期的泄漏 GDI 资源。也不是那么容易。
-
我一直在思考这个问题。我养成了在编写代码时快速检查类型以查看它们是否继承自
IDisposable的习惯。如果他们这样做,我将它们包装在using中,在它们需要生存的范围内。它对现有代码没有任何作用,但我只是想我会提到它。 -
查看这篇文章,您可以在其中使用 Visual Studio 代码分析在编译时检测 iDisposable 问题:stackoverflow.com/a/6213977/2862
标签: c# .net idisposable memory-leaks