我有一个来自处于GC周期中间的NT服务(使用C#/.NET 4.5.2实现)的完整进程转储。当我将其加载到WinDbg并尝试运行!DumpHeap -stat
(或DumpHeap
的任何其他变体)时,我会收到以下警告:
垃圾收集器数据结构的状态不适合遍历。它要么处于"计划阶段",对象在其中移动,要么处于gc堆的初始化或关闭。与显示、查找或遍历对象以及gc堆段相关的命令可能无法正常工作!笨蛋和!verifyheap可能会错误地抱怨堆一致性错误。
不幸的是,我无法(轻松)在GC之外获得干净的内存转储(我显然不知道什么时候会发生,我需要一个可管理大小的转储-我正在查看的进程会泄漏内存,有时会达到18GB;这太大了,以至于大多数堆查找在WinDbg中都需要40分钟以上。)
即使我使用-short
参数只生成对象地址(将它们输入到WinDbg宏中),也会显示此警告消息-不幸的是,警告消息中的单词会作为输入参数传递到宏中,宏会爆炸。(宏是这个问题的变体,我正试图在大量对象实例上运行!GCRoot
。)
有没有办法在WinDbg中禁用此警告消息?(DumpHeap
是SOS的一部分,所以如果可能的话,我想它需要在那里禁用。)
编辑:为了清楚起见,我从DumpHeap
和其他命令中得到了有用的输出(它们看起来基本一致),只是所有输出都以上述警告开始,即使使用-short
也是如此。这意味着我无法将输出输入到其他命令中。
您的问题
我理解-short
输出包含该消息是一个遗憾。IMHO无法禁用该消息。
您可以使用pykd(Codeplex)来过滤文本。您需要dbgCommand()
函数来发出!dumpheap
命令。您将返回一个带有命令输出的字符串,然后可以过滤文本。接下来,您可以使用dprint()
将文本推回调试器。
其他想法
-
当.NET不在垃圾回收过程中时,也许您想尝试进行转储。
-
加快速度:
- sosex有一个
!bhi
命令来构建堆索引 -
netext有一个
!windex
命令来构建堆索引。它甚至有一个类似于!dumpheap
的命令,可以以.foreach
的方式使用(来自网站):.foreach({$addr} {!windex -short -type *.HttpRequest}){!wselect _url.m_String from {$addr} }
- sosex有一个
-
PyKd:当你在做的时候,你也可以在Python中重写
.foreach
循环,并在Python中完成!do
部分,允许你根据对象的内容等来过滤对象,这样你就可以通过使用更直观的脚本语言来获得一些时间。