2

我已经实现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”),看到一个不断增加的数字。

4

4 回答 4

1

追踪这一点的最好方法是使用内存分析器......有很多可供选择。

.NET 内存分析工具

于 2012-05-22T21:54:39.993 回答
1

确保你使用

try
{
}
finally 
{ 
   youDisposableObject.Dispose(); 
} 

或者

using (yourDisposableObject) {}

对于您实施“处置”的每个对象

如果您无需任何需要就对某些对象实现了终结器,请删除它们

如果之后仍然无法修复它,则必须使用内存分析器

于 2012-05-22T22:00:58.653 回答
1

这里有一篇文章描述了如何使用 SOS.dll 来完成,这里有一篇更全面的文章

根据您使用的 Visual Studio 版本(Premium 或 Ultimate),您还可以使用常规代码分析工具来帮助查找代码中可能导致内存泄漏的问题。(这里有详细信息)

当然,在托管代码中,内存泄漏与在非托管代码中有些不同。在非托管代码中,显式分配和解除分配内存,内存泄漏是由于未能解除分配内存造成的。

在 .NET 中,内存泄漏来自于挂在对象上的时间比预期的要长。只需遵循尽可能使用using语句的最佳实践,并仔细规划变量的范围,就可以在很大程度上避免这种情况。

于 2012-05-22T22:01:44.660 回答
1

我刚刚在我的 c# 应用程序中遇到了同样的问题,并使用了(实际上是试用版) dotTrace 内存分析器,这非常有帮助。

仍然需要一些时间来定位发生泄漏的实际代码行。因此,不要指望该工具会立即识别出罪魁祸首。

于 2012-05-22T22:02:29.570 回答