我已经实现了Dispose
...支持它的所有地方。我正在删除所有事件处理程序。我不是在调用本机代码。
我甚至遍历每个字典并将值设置为null并在所有项目上调用.Clear()。
问题:
如何判断代码泄漏的位置?
我首先通过测试过夜发现泄漏。它使用固定数量的内存,因此它应该增长,然后变得有些静止。然后我做了前景线程显示内存,如下所示:
if (key.KeyChar == 'g')
{
long pre = GC.GetTotalMemory(false);
long post = GC.GetTotalMemory(true);
Console.WriteLine("{2} Pre:{0} \tPost:{1}", pre, post, System.DateTime.Now);
GC.Collect();
}
我跑了几次(几个小时,偶尔按下“g”)并看到一个不断增加的数字。
答案 0 :(得分:1)
跟踪此问题的最佳方法是使用内存分析器......有很多选择。
答案 1 :(得分:1)
确保使用
try
{
}
finally
{
youDisposableObject.Dispose();
}
或
using (yourDisposableObject) {}
到你实现的每个对象“Dispose”
如果您在没有任何需要的情况下为某些对象实现了终结器,请将其删除
如果在此之后仍无法修复,则必须使用内存分析器
答案 2 :(得分:1)
有一篇文章描述了如何使用SOS.dll here和更全面的here来完成它。
根据您正在使用的Visual Studio版本(Premium或Ultimate),您还可以使用常规代码分析工具来帮助查找代码中可能导致内存泄漏的问题。 (详情here)
当然,在托管代码中,内存泄漏与非托管代码中的内存泄漏略有不同。在非托管代码中,您分配和释放内存明确性,内存泄漏是由于无法释放内存而导致的。
在.NET中,内存泄漏来自于挂在对象上的时间超过预期。只要遵循尽可能使用using语句的最佳实践,并仔细规划变量的范围,就可以在很大程度上避免这种情况。
答案 3 :(得分:1)
我在我的c#应用程序中遇到了同样的问题并使用了(实际上是试用版) dotTrace memory profiler非常有帮助。
仍然需要一些时间来本地化发生泄漏的实际代码行。因此,不要指望该工具立即立即识别罪魁祸首。