My problem is this:
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
The way I read this output is that I have 74,247 Microsoft.Internal.ReadLock
instances on my heap. However, some of them are probably pending collection.
I want to display only those which are not pending collection.
For example, 0000000080f88e90
is the address of one of these objects and it is garbage. I know it, because:
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
As one can see, both sosex.mroot
and sosex.refs
indicate no one references it, plus dumping its fields reveals that it was disposed through IDisposable
, so it makes sense that the object is garbage (I know that being disposed does not imply the object is garbage, but it is in this case).
Now I want to display all those instances which are not garbage. I guess I am to use the .foreach
command. Something like this:
.foreach(entry {!dumpheap -type Microsoft.Internal.ReadLock -short}){.if (???) {.printf "%p\n", entry} }
My problem is that I have no idea what goes into the .if
condition.
I am able to inspect the _isDisposed field like this:
0:000> dd 0000000080f88e90+10 L1
00000000`80f88ea0 00000001
But .if
expects an expression and all I have is a command output. If I knew how to extract information from the command output and arrange it as an expression then I could use it as the .if
condition and be good.
So, my question is this - is there a way to get the field value as an expression suitable for .if
? Alternatively, is it possible to parse the command output in a way suitable for using the result as the .if
condition?
!mroot
or!refs
command? Although, testing the value of_isDisposable
is enough in this case, it may not be so for other objects, where the only reliable way is to check if the object is rooted. Meaning running a command like!mroot
or!refs
or something similar. But then, how to .if on the result? – Saporific