【问题标题】:How can I determine what part of my application is leaking memory?如何确定我的应用程序的哪一部分正在泄漏内存?
【发布时间】:2012-05-22 21:48:59
【问题描述】:

我已经在所有支持它的地方实现了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”一次),看到一个不断增加的数字。

【问题讨论】:

  • 您是否随时与 COM 对象进行交互?
  • 是什么让你觉得它在泄露?
  • 将您的应用程序浸入水中,看看气泡从哪里冒出来。
  • @vcsjones 根据您的要求更新
  • @MichaelTodd 我只是在调用 .NET 对象……尽管它们可能在后台调用 COM。这有关系吗?

标签: c# visual-studio-2010 memory-leaks dispose


【解决方案1】:

跟踪此问题的最佳方法是使用内存分析器...有很多可供选择。

.NET Memory Profiling Tools

【讨论】:

    【解决方案2】:

    确保你使用

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

    using (yourDisposableObject) {}
    

    对你实现“Dispose”的每个对象

    如果您在不需要的情况下对某些对象实现了终结器,请将它们删除

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

    【讨论】:

      【解决方案3】:

      有一篇文章描述了如何使用 SOS.dll here 和更全面的一篇文章 here

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

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

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 2012-06-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多