27

我可以使用一些建议来追踪 C# 中内存泄漏的原因。我了解什么是内存泄漏,并且知道它们为什么会在 C# 中发生,但我想知道您过去使用过哪些工具/策略来解决它们?

我正在使用.NET Memory Profiler,我发现我的一个巨大的主要对象在我关闭它管理的窗口后仍留在内存中,但我不确定如何处理它的所有链接。

如果我不够清楚,只需发布​​一个问题的答案,我将编辑我的问题作为回应。谢谢!

4

2 回答 2

39

进入调试器,然后在“立即”窗口中键入:

.load C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll

sos.dll 的路径各不相同。找出正确路径的方法是在“模块”窗格中查找 mscorwks.dll。无论从哪里加载,都是 sos.dll 的正确路径。

然后输入:

System.GC.Collect()

这将确保收集到任何无法到达的东西。然后输入:

!DumpHeap -type <some-type-name>

这将向您显示所有现有实例的表格以及地址。您可以像这样找出使实例保持活动状态的原因:

!gcroot <some-address>
于 2008-10-22T23:56:28.063 回答
8

.NET Memory Profiler 是一款出色的工具,我经常使用它来诊断 WPF 应用程序中的内存泄漏。

我相信您知道,使用它的一个好方法是在使用特定功能之前拍摄快照,然后在使用它、关闭窗口等之后拍摄第二张快照。比较两个快照时,您可以查看有多少某种类型的对象被分配但没有被释放:这是一个泄漏。

双击一个类型后,分析器将向您显示使该类型对象保持活动状态的最短根路径。.NET 对象在 WPF 中泄漏的方式有很多种,因此发布您看到的根路径应该有助于确定最终原因。但是,一般来说,尝试了解为什么这些对象会保留您的对象,并查看是否有某种方法可以在窗口关闭时分离您的事件处理程序、绑定等。

我最近发布了一篇关于可能由某些绑定引起的特定内存泄漏的博客文章;对于特定类型的泄漏,那里的代码对于查找有问题的绑定很有用。

于 2008-10-23T04:54:48.523 回答