在WinDbg内部仅转储托管对象和/或统计信息 [英] Dumping only rooted managed objects and/or statistics on them inside WinDbg

查看:143
本文介绍了在WinDbg内部仅转储托管对象和/或统计信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是,$ code> dumpheap -stat 返回了很多对象,我不知道哪些是根,哪些不是。

My problem is that dumpheap -stat returns an awful lot of objects and I have no idea which ones are rooted and which ones are not.

嗯,如果我运行!mroot !refs 命令一个单独的地址,但是这种方法不能很好地扩展到 dumpheap 报告的数千个对象。

Well, I can if I run the !mroot or !refs command on an individual address, but this approach does not scale very well to thousands of objects reported by dumpheap.

例如, dumpheap -stat 包含以下行:

000007fef3d14088    74247      2375904 Microsoft.Internal.ReadLock

哇,74,247个实例。但是,运行

Wow, 74,247 instances. However, running

.logopen c:\tmp\2\log.txt;.foreach (entry {!dumpheap -type Microsoft.Internal.ReadLock -short}){!refs ${entry} -target};.logclose

显示, DumpHeap 报告的每个实例实际上是无人认领的垃圾!

reveals that each and every instance reported by DumpHeap is actually unreclaimed garbage!

我如何发现每个而且每个实例都是垃圾是另一个问题。我不得不将所有 NONE 字符串提取到一个文件,并将所有对象引用字符串到另一个文件,然后比较数字的每个文件中的行。当然有一个更好的方法: - (。

How I found that each and every instance is garbage is another problem. I had to extract all the NONE strings to one file and all the Objects referencing strings to another and then compared the number of lines in every file. Surely there is a better way :-(.

无论如何,我想知道如何专注于根植物体,理想情况下,我想得到统计数据以及关于这些对象的细节。

Anyway, I would like to know how to focus on the rooted objects only. Ideally, I would like to get the statistics as well as details on such objects.

推荐答案

你的所有对象的循环已经很好,只有!refs命令需要替换为只找到根对象的其他东西,我的示例使用字符串,因为我没有使用ReadLocks的应用程序。

Your loop over all objects is already great, just the !refs command needs to be replaced by something else which finds only rooted objects. My example uses Strings, because I don't have an application available using ReadLocks.

有两个可能的输出!引用的对象输出例如

There are two possible outputs of the !refs command. A referenced object outputs e.g.

Objects referencing 02703f18 (System.String):
follow 02703a88       128   System.Globalization.NumberFormatInfo

垃圾对象如下所示:

Objects referencing 02703f30 (System.String):
NONE

您只对第一行的地址感兴趣,以防第二行出现包含跟随一词。幸运的是,地址等于 $ {entry} ,所以我们实际上不需要它。否则,您将处于同样的问题,如我我是

You're only interested in the address of the first line in case the second line contains the word "follows". Luckily, the address is equal to ${entry}, so we actually don't need it. Otherwise you would be in the same trouble like I am.

这带给我一个这个问题关于.if

您可以再次使用.foreach的输出!refs。我们先来看看一个对象:

You can use .foreach again on the output of !refs. Let's have a look at this on a single object first:

.foreach (reftoken {!refs 027045cc -target}) { .printf "${reftoken}\n" }

每行一行一个字,我们感兴趣只有在第五个,这意味着我们可以初步跳过4个项目,然后跳过其余的,这给了我们

This prints one word per line and we are interested only in the fifth, which means we can initially skip 4 items and then skip the rest, which gives us

.foreach /pS 4 /ps 3 (reftoken {!refs 027045cc -target}) { .printf "${reftoken}\n" }

为了稳健的目的,让我们使用 / ps 99

接下来我们需要检查这个标记是否等于 / em>,这是由

For robustness purposes, let's use /ps 99.
Next we need to check if this token equals follow, which is done by

.if ($sicmp("${reftoken}","follow") == 0) { .echo found follow }

将它们组合在一起:

.foreach (entry {!dumpheap -type System.String -short})
{
   .foreach /pS 4 /ps 99 (reftoken {!refs ${entry} -target}) 
   { 
      .if ($sicmp("${reftoken}","follow") == 0) 
      { 
            .printf "${entry}\n"
      } 
   }
}

在一行中:

 .foreach (entry {!dumpheap -type System.String -short}){.foreach /pS 4 /ps 99 (reftoken {!refs ${entry} -target}) {.if ($sicmp("${reftoken}","follow") == 0) {.printf "${entry}\n"}}}

当然,您可以用任何其他对您的情况有帮助的命令替换 .print

Of course you can replace .print by any other command which is helpful in your situation.

我希望您可以调整此示例以使用ReadLock。

I hope you can adapt this sample to use ReadLock.

这篇关于在WinDbg内部仅转储托管对象和/或统计信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆