我能否从WinDbg运行.NET垃圾回收?

17

我正在研究为什么一个托管进程使用了大量的内存。是否有一种方法可以在WinDbg中运行GC.Collect(3),以便我可以专注于实际的内存分配?

4个回答

5

2
我很感兴趣。你能解释一下为什么你认为这不是必要的吗? - Roger Lipscombe
这并不是必需的,因为Rico Mariani关于追踪托管内存泄漏的信息描述了一种过程,可以确定应用程序中可能存在哪些泄漏或堆上的内容,而无需强制进行垃圾回收。 - Grant Wagner
3
如果有许多可以被垃圾回收的对象散落在周围,您在Rico Mariani博客文章的第7步中是否经常会遇到问题?这似乎是一个常见的挫败感,需要对一个接一个的对象执行!gcroot操作,但最终找不到任何引用链。 - IV.
@IV 我同意 - 这真的很痛苦。我经常使用“disposed”标志作为此信息的代理,但并非所有类都实现IDisposeable接口或在其实现中使用此标志。例如:.foreach (obj {!dumpheap -type Oracle.DataAccess.Client.OracleConnection -short}) { .printf "\n\n"; .printf "Object at: %p\nDisposed: %d", ${obj}, poi(${obj}+12a) & 0x00FF; } - Thomas Bratt
在一个巨大的转储中,如果没有进行GC.Collect,分析内存泄漏是非常困难的。 - cskwg

3

我不相信你可以从WinDbg触发GC。

以下是一些我依赖的有用的内存分配跟踪工具:

  • SOSEX -- 一个进一步的扩展,用于补充SOS,它添加了!dumpgen来从特定代中转储对象(非常适合确定LOH和Gen 2中的内容),以及!refs命令,它将为对象提供父引用。
  • .Net Memory Profiler -- 这是一个非常有用的工具,当交互式运行时,但它还包含从转储文件加载的选项。这提供了一种相当直观的方式来跟踪内存使用情况。价值250美元,但他们也有14天的试用期。

2

WinDBG首先是一个Win32/Kernel调试器。因此,您可能想尝试其中一个托管调试器,例如mDBG。但我曾经为MSFT做过.NET调试支持,而我从未需要类似的工具来解决内存泄漏问题。


首先,肯定是Win32/Kernel调试器吧? - Mark
3
我从未需要过这样的东西来排除内存泄漏问题,那么你使用了什么呢? - Damian Powell

0

嗨,罗杰,希望你的内存泄漏问题现在已经解决了。:-)

首先要确保它是“托管内存泄漏”。也就是说,当您查看性能监视器计数器.NET CLR Memory -># Bytes in all heaps时,与该进程的相同进程的计数器Process -> Private Bytes以相同的速度增加。如果是这样,那么您可以使用上面描述的技术。

如果不是,则可能存在由运行托管代码引起的本机泄漏。我见过的最常见泄漏是与在进程中加载但未卸载的.NET程序集相关的问题。在Perfmon中,这看起来像是本机内存泄漏。

我建议您尝试在DebugDiag中运行一个泄漏规则,并查看内存报告显示的泄漏调用堆栈。

这里还有另一个关于此主题的绝佳资源: 我有内存泄漏!!!我该怎么办?(定义“哪里”)

谢谢, 亚伦


已经解决了。我使用其他答案中的技术找出了“泄漏”的原因。它是一堆PaintEventArgs对象之类的东西。原因是一个动画进度条,每秒重绘10次。所以这实际上不是泄漏,只是控件使用了太多内存。 - Roger Lipscombe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接