!DumpHeap - 可以禁用GC警告吗?

时间:2015-11-24 23:18:34

标签: .net service memory-leaks windbg sos

我有一个来自NT服务的完整进程转储(使用C#/ .NET 4.5.2实现),这是在GC周期的中间。当我将其加载到WinDbg并尝试运行DumpHeap(或-short的任何其他变体)时,我收到此警告:

  

垃圾收集器数据结构未处于遍历的有效状态。它处于"计划阶段,"移动对象的位置,或者我们处于gc堆的初始化或关闭状态。与显示,查找或遍历对象以及gc堆段相关的命令可能无法正常工作。 !dumpheap和!verifyheap可能错误地抱怨堆一致性错误。

不幸的是,我不能(轻松)在GC之外获得一个干净的内存转储(我显然不知道它何时发生,我需要一些可管理的转储 - 我正在查看泄漏的过程内存并且有时达到18 GB;这是如此之大,以至于大多数堆查找在WinDbg中占用超过40分钟。)

即使我使用!GCRoot参数仅生成对象地址(将它们输入到WinDbg宏中),此警告消息也会显示 - 不幸的是,警告消息的单词作为输入参数传递给宏,宏爆炸了。 (该宏是this question的变体,我尝试在大量对象实例上运行DumpHeap。)

有没有办法在WinDbg中禁用此警告消息? (DumpHeap是SOS的一部分,所以我想如果可能的话,需要在那里禁用它。)

编辑:为了清楚起见,我从-short和其他命令(看起来大致一致)得到有用的输出,只是所有输出都是从上面开始的警告,即使使用add()。这意味着我无法将输出提供给其他命令。

1 个答案:

答案 0 :(得分:1)

您的问题

我理解遗憾的是-short输出包含该消息。恕我直言,该消息无法被禁用。

您可以使用pykd (Codeplex)过滤文字。您需要dbgCommand()函数才能发出!dumpheap命令。您将使用命令的输出返回一个字符串,然后您可以过滤文本。接下来,您可以使用dprint()将文本推送回调试器。

其他想法

  1. 也许您想尝试taking a dump when .NET is not in the middle of a garbage collection

  2. 加快速度:

    • 有一个!bhi命令来构建堆索引。
    • netext有一个!windex命令来构建堆索引。它甚至有一个类似!dumpheap的命令,可以.foreach方式使用(来自网站):

      .foreach({$addr} {!windex -short -type *.HttpRequest}){!wselect _url.m_String from {$addr} }
      
  3. PyKd:虽然您正在使用它,但您也可以在Python中重写.foreach循环并在Python中执行!do部分,允许您基于过滤对象关于他们的内容等,所以你可以通过使用更直观的脚本语言来获得一些时间。