次のコマンドの各アドレスに対して !refs コマンドを実行したい
!dumpgen 2 -type System.DateTime[]
これを行う方法.次のようにループを作成できることを知っています
.foreach (myvar {!dumpgen 2 -type System.DateTime[]})
しかし、!refs を使用してループで使用できるオブジェクト アドレスにアクセスするにはどうすればよいでしょうか?
!dumpgen
-short
has のような引数はありません!dumpheap
。これよりも簡単な答えが欲しいです。
ヒープのアドレスを取得する
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>
アドレスのみを出力する-short
パラメーター onを使用します。!dumpheap
オブジェクトのこのアドレスは、他のコマンドで処理できます。
また、注: を使用-type
すると、他のタイプも発生する可能性があります。-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 ヒープに対して個別に行う必要があります。それらのいくつかがあるかもしれません。
別の醜い解決策は、
!dumpheap -short
および-type
または-mt
)!gcgen
これを行う方法は次のとおりです(読みやすいようにフォーマットされており、すべてを1行にまとめています):
.foreach (addr {!dumpheap -short -mt 53ab0d48}) {
.foreach /pS 1 (gen {!gcgen ${addr}}) {
.if ($scmp("${gen}","2")==0) {
!refs ${addr}
}
}
}
where53ab0d48
は探しているタイプのメソッド テーブルで、 は"2"
必要な世代です。/pS 1
の出力で「Gen」という単語をスキップします!gcgen
。
短所: すべてのオブジェクトで動作するため、遅くなる可能性があります。