您对所有对象的循环已经很棒了,只是需要将 !refs 命令替换为仅找到根对象的其他命令。我的示例使用字符串,因为我没有使用 ReadLocks 的应用程序。
!refs 命令有两种可能的输出。引用的对象输出例如
Objects referencing 02703f18 (System.String):
follow 02703a88 128 System.Globalization.NumberFormatInfo
垃圾对象如下所示:
Objects referencing 02703f30 (System.String):
NONE
如果第二行包含单词“follows”,您只对第一行的地址感兴趣。幸运的是,地址等于${entry}
,所以我们实际上不需要它。否则你会遇到和我一样的麻烦。
这让我想到了这个关于 .if的问题。
您可以在 !refs 的输出上再次使用 .foreach。让我们首先在单个对象上看一下:
.foreach (reftoken {!refs 027045cc -target}) { .printf "${reftoken}\n" }
这会每行打印一个单词,我们只对第五个单词感兴趣,这意味着我们最初可以跳过 4 个项目,然后跳过其余的,这给了我们
.foreach /pS 4 /ps 3 (reftoken {!refs 027045cc -target}) { .printf "${reftoken}\n" }
出于稳健性目的,让我们使用/ps 99
.
接下来我们需要检查这个令牌是否等于follow,这是由
.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替换为对您的情况有帮助的任何其他命令。
我希望您可以修改此示例以使用 ReadLock。