在应用程序中调试巨大的内存泄漏

时间:2010-01-11 18:49:45

标签: .net memory memory-leaks

我的应用程序刚刚泄露了1.5GB的内存。我想因为我没有大量的数据可供我使用,我假设它泄露了内存,但它也可能只是抓住它。

我目前正在使用perfmon收集尽可能多的信息,以试图了解可能导致问题的原因。我目前没有很多线索,并且希望得到更多来自这里的人的提示。

  1. 我可以说的第一件事就是我没有在任何课程中实现IDisposable。但是,我知道我不会在任何GUI元素上调用Dispose,比如SolidColorBrush。由于我的应用程序不是图形密集型的任何方式,我认为这不会导致问题。但是,我会添加必要的电话。

  2. 我不知道我是否在框架中使用任何其他类来实现IDisposable。我读了一篇关于FxCop的帖子here on SO。我安装并使用它来分析我的程序集,但它似乎只检查我自己的类的IDisposable的正确实现。还有其他工具可以告诉我所有实现IDisposable的类吗?

  3. 我目前正在我的应用程序中使用WF,并且WF不断被启动和完成。 Perfmon显示WF正在正常结束,我正在使用“using”关键字,我理解处理适当的处理方式。

  4. 是否有一种简单的方法可以判断“泄露”的内存是来自非托管代码还是托管代码?

  5. 在我收到OOM例外时,应用程序使用了77k +句柄。

  6. 有关如何继续下一步的任何提示将不胜感激。我打算再次运行应用程序并监视性能计数器,并可能会删除某些调用。我还可以运行模拟以进行比较,因为在该模式下它不会调用我的C DLL。

5 个答案:

答案 0 :(得分:4)

答案 1 :(得分:2)

Red-Gate有一个内存分析器(http://www.red-gate.com/products/ants_memory_profiler/index.htm),对于这些事情非常有用。我强烈推荐它。 30天试用。

兰迪

答案 2 :(得分:2)

在你去投资工具之前,你应该试着找出泄漏的东西......

你已经附上了perfmon,这很棒。我会监视以下的perfcounters。

过程\ PrivateBytes 进程\处理计数 过程\的NonPagedPool

.NET CLR Memory *

如果你的私有字节增长,以及.NET CLR Memory \ BytesInAllHeaps,它指向一个托管泄漏。后续步骤:使用CLR Profiler进行进程转储和分析,或者将windbg.exe附加到进程,加载sos扩展dll,并分析托管堆是否存在泄漏。

如果私有字节增长,而.NET CLR Memory *计数器没有相应的增加,那么它指向非托管泄漏。您必须将windbg.exe附加到进程并使用!heap扩展来检查进程堆。

如果您看到单调增加的HandleCount以及NonPagedPool,则会出现句柄泄漏 - 这可能是托管代码或本机代码。您必须弄清楚哪些句柄正在泄漏 - 您可以使用sysinternals中的processmon.exe来获取句柄列表,并进一步调查。

希望这有帮助。

答案 3 :(得分:0)

Use CLR Profiler弄清楚你在泄漏什么。然后解决它。

答案 4 :(得分:0)

不是直接回答你的问题,但我总是使用Process Explorer来显示进程虚拟大小,工作集,Gen 0,1和2集合以及私有字节(与非托管内存相关)。基本上它只是常规窗口任务管理器和性能计数器的一个很好的UI。可以帮助您观察应用程序与内存相关的行为。