运行 来自循环的命令
Running a command from the loop
我想运行 !refs 命令针对来自以下命令的每个地址
!dumpgen 2 -type System.DateTime[]
这怎么可能done.I知道可以按如下方式创建循环
.foreach (myvar {!dumpgen 2 -type System.DateTime[]})
但是我怎样才能访问可以在 !refs 循环中使用的对象地址?
!dumpgen
没有像 !dumpheap
那样的 -short
论点,我真的很想看到比这个更简单的答案。
方法 1:手动转储一代
获取堆的地址
0:003> !eeheap -gc
Number of GC Heaps: 1
generation 0 starts at 0x026f1018
generation 1 starts at 0x026f100c
generation 2 starts at 0x026f1000
使用地址将输出限制为您想要的世代:
!dumpheap -type X <start> <end>
在!dumpheap
上使用-short
参数,只输出地址。然后可以通过其他命令处理该对象的地址。
另请注意:使用 -type
也可能导致其他类型。最好将方法 table 与 -mt
结合使用,因为只有这样才能保证类型的唯一性。如果您没有从其他地方获得,请使用 !name2ee
。
完整的会话可能如下所示:
0:003> !dumpheap -stat
total 345 objects
Statistics:
MT Count TotalSize Class Name
53ab421c 1 12 System.Text.DecoderExceptionFallback
[...]
53ab0d48 135 6640 System.String
53a84518 26 9452 System.Object[]
Total 345 objects
0:003> !eeheap -gc
Number of GC Heaps: 1
generation 0 starts at 0x026f1018
generation 1 starts at 0x026f100c
generation 2 starts at 0x026f1000
[...]
0:003> !name2ee *!System.String
Module: 53841000 (mscorlib.dll)
Token: 0x02000024
MethodTable: 53ab0d48
[...]
0:003> !dumpheap -short -mt 53ab0d48 0x026f1000 0x026f100c
(好吧,我所有的字符串似乎都在第 0 代,该死的:-)
0:003> .foreach (addr {!dumpheap -short -mt 53ab0d48 0x026f1018}) {!refs ${addr}}
缺点:您需要对所有 GC 堆分别执行此操作。可能有几个。
方法 2:决定生成每个对象
另一个丑陋的解决方案是
- 转储所有对象地址(
!dumpheap -short
和-type
或-mt
)
- 通过
!gcgen
查询每个对象的生成
- 根据生成,执行命令
操作方法如下(为了便于阅读而格式化,全部放在一行中):
.foreach (addr {!dumpheap -short -mt 53ab0d48}) {
.foreach /pS 1 (gen {!gcgen ${addr}}) {
.if ($scmp("${gen}","2")==0) {
!refs ${addr}
}
}
}
其中 53ab0d48
是您要查找的类型的方法 table,"2"
是您想要的世代。 /pS 1
跳过 !gcgen
输出中的单词 "Gen"。
缺点:可能会很慢,因为它适用于所有对象。
我想运行 !refs 命令针对来自以下命令的每个地址
!dumpgen 2 -type System.DateTime[]
这怎么可能done.I知道可以按如下方式创建循环
.foreach (myvar {!dumpgen 2 -type System.DateTime[]})
但是我怎样才能访问可以在 !refs 循环中使用的对象地址?
!dumpgen
没有像 !dumpheap
那样的 -short
论点,我真的很想看到比这个更简单的答案。
方法 1:手动转储一代
获取堆的地址
0:003> !eeheap -gc Number of GC Heaps: 1 generation 0 starts at 0x026f1018 generation 1 starts at 0x026f100c generation 2 starts at 0x026f1000
使用地址将输出限制为您想要的世代:
!dumpheap -type X <start> <end>
在
!dumpheap
上使用-short
参数,只输出地址。然后可以通过其他命令处理该对象的地址。
另请注意:使用 -type
也可能导致其他类型。最好将方法 table 与 -mt
结合使用,因为只有这样才能保证类型的唯一性。如果您没有从其他地方获得,请使用 !name2ee
。
完整的会话可能如下所示:
0:003> !dumpheap -stat
total 345 objects
Statistics:
MT Count TotalSize Class Name
53ab421c 1 12 System.Text.DecoderExceptionFallback
[...]
53ab0d48 135 6640 System.String
53a84518 26 9452 System.Object[]
Total 345 objects
0:003> !eeheap -gc
Number of GC Heaps: 1
generation 0 starts at 0x026f1018
generation 1 starts at 0x026f100c
generation 2 starts at 0x026f1000
[...]
0:003> !name2ee *!System.String
Module: 53841000 (mscorlib.dll)
Token: 0x02000024
MethodTable: 53ab0d48
[...]
0:003> !dumpheap -short -mt 53ab0d48 0x026f1000 0x026f100c
(好吧,我所有的字符串似乎都在第 0 代,该死的:-)
0:003> .foreach (addr {!dumpheap -short -mt 53ab0d48 0x026f1018}) {!refs ${addr}}
缺点:您需要对所有 GC 堆分别执行此操作。可能有几个。
方法 2:决定生成每个对象
另一个丑陋的解决方案是
- 转储所有对象地址(
!dumpheap -short
和-type
或-mt
) - 通过
!gcgen
查询每个对象的生成
- 根据生成,执行命令
操作方法如下(为了便于阅读而格式化,全部放在一行中):
.foreach (addr {!dumpheap -short -mt 53ab0d48}) {
.foreach /pS 1 (gen {!gcgen ${addr}}) {
.if ($scmp("${gen}","2")==0) {
!refs ${addr}
}
}
}
其中 53ab0d48
是您要查找的类型的方法 table,"2"
是您想要的世代。 /pS 1
跳过 !gcgen
输出中的单词 "Gen"。
缺点:可能会很慢,因为它适用于所有对象。