我的问题是:
0:000> !DumpHeap -type Microsoft.Internal.ReadLock -stat ------------------------------ Heap 0 total 0 objects ------------------------------ Heap 1 total 0 objects ------------------------------ Heap 2 total 0 objects ------------------------------ Heap 3 total 0 objects ------------------------------ total 0 objects Statistics: MT Count TotalSize Class Name 000007fef3d14088 74247 2375904 Microsoft.Internal.ReadLock Total 74247 objects
我读取此输出的方式是Microsoft.Internal.ReadLock
我的堆上有74,247个实例.但是,其中一些可能正在等待收集.
我想只显示那些没有待处理的集合.
例如,0000000080f88e90
是其中一个对象的地址,它是垃圾.我知道,因为:
0:000> !mroot 0000000080f88e90 No root paths were found. 0:000> !refs 0000000080f88e90 -target Objects referencing 0000000080f88e90 (Microsoft.Internal.ReadLock): NONE 0:000> !do 0000000080f88e90 Name: Microsoft.Internal.ReadLock MethodTable: 000007fef3d14088 EEClass: 000007fef3c63410 Size: 32(0x20) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.ComponentModel.Composition\v4.0_4.0.0.0__b77a5c561934e089\System.ComponentModel.Composition.dll Fields: MT Field Offset Type VT Attr Value Name 000007fef3d13fb0 400001e 8 ...oft.Internal.Lock 0 instance 0000000080001010 _lock 000007fef0a8c7d8 400001f 10 System.Int32 1 instance 1 _isDisposed
正如人们可以看到的那样,sosex.mroot
并且sosex.refs
表明没有人引用它,加上转储它的字段显示它被处理掉了IDisposable
,所以有意义的是对象是垃圾(我知道被处置并不意味着对象是垃圾,但它是在这种情况下).
现在我想显示所有那些不是垃圾的实例.我想我要使用.foreach
命令.像这样的东西:
.foreach(entry {!dumpheap -type Microsoft.Internal.ReadLock -short}){.if (???) {.printf "%p\n", entry} }
我的问题是我不知道是什么.if
情况.
我能够像这样检查_isDisposed字段:
0:000> dd 0000000080f88e90+10 L1 00000000`80f88ea0 00000001
但是.if
期望一个表达式,我所拥有的只是一个命令输出.如果我知道如何从命令输出中提取信息并将其作为表达式排列,那么我可以将其用作.if
条件并且很好.
所以,我的问题是 - 有没有办法让字段值作为适合的表达式.if
?或者,是否可以以适合使用结果作为.if
条件的方式解析命令输出?
我没有使用ReadLock对象的示例,但我尝试使用Strings,这是我的结果:
.foreach (entry {!dumpheap -short -type Microsoft.Internal.ReadLock}) { .if (poi(${entry}+10) == 1) { .printf "%p\n", ${entry} } }
我正在使用poi()从地址获取指针大小数据.另请注意,我在$ {entry}中都没有输入 poi()和.printf.您可能也喜欢!在.if中执行$ {entry}.
在一行中复制/粘贴:
.foreach (entry {!dumpheap -short -type Microsoft.Internal.ReadLock}) {.if (poi(${entry}+10) == 1) {.printf "%p\n", ${entry}}}