如何确定应用程序的哪个部分正在泄漏内存

本文关键字:泄漏 内存 个部 何确定 应用程序 | 更新日期: 2023-09-27 18:35:05

我已经实现了Dispose...所有支持它的地方。 我正在删除所有事件处理程序。 我不是在调用本机代码。

我什至遍历每个字典并将值设置为 null 并调用 .清除() 在所有项目上。

问题:

如何找出我的代码泄漏的位置?

我首先通过在一夜之间在测试中运行它来发现泄漏。 它使用固定数量的内存,因此它应该增长,然后变得有些静态。 然后,我使前景线程显示内存如下所示:

            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"),并看到一个不断增加的数字。

如何确定应用程序的哪个部分正在泄漏内存

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

.NET 内存分析工具

确保使用

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

using (yourDisposableObject) {}

到您实现的每个对象"释放"

如果对某些对象实现了终结器而不需要,请将其删除

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

一篇文章描述了如何使用 SOS.dll 在这里,还有一篇更全面的文章。

根据所使用的 Visual Studio 版本(高级版或旗舰版),还可以使用常规代码分析工具来帮助查找代码中可能导致内存泄漏的问题。 (详情请见此处)

当然,在托管代码

中,内存泄漏与非托管代码中的内存泄漏略有不同。 在非托管代码中,在分配和取消分配内存显式的情况下,内存泄漏是由于未能释放内存而导致的。

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

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

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