One of class has many object present in .NET heap as discovered through following sos command.
!dumpheap -stat -type MyClass
Statistics:
MT Count TotalSize Class Name
00007ff8e6253494 1700 164123 MyNameSpace.MyClass
I need to find the instances of those objects that have ObjSize greater then 5 MB. I know I can list out objsize of all 1700 instances of MyClass using following.
.foreach (res {!DumpHeap -short -MT 00007ff8e6253494 }) {.if ( (!objsize res) > 41943040) {.echo res; !objsize res}}
With the script above, I don't get any results although there are object instances greater than 5MB. I think problem may be that output of objsize is follows
20288 (0x4f40) bytes
Its a string which make it harder to compare against any threshold. How can I get this script to only list objects that has objsize larger then 5MB?
Creating complex scripts in WinDbg is quite error prone. In such situations, I switch to PyKd, which is a WinDbg extension that uses Python.
In the following, I'll only cover the missing piece in your puzzle, which is the parts that does not work:
.if ( (!objsize res) > 41943040) {.echo res; !objsize res}
Here's my starting point:
0:009> !dumpheap -min 2000
Address MT Size
00000087c6041fe8 000007f81ea5f058 10158
00000087d6021018 000007f81ea3f1b8 8736
00000087d6023658 000007f81ea3f1b8 8192
00000087d6025658 000007f81ea3f1b8 16352
00000087d6029638 000007f81ea3f1b8 32672
You can write a script like this (no error handling!)
from pykd import *
import re
import sys
objsizeStr = dbgCommand("!objsize "+sys.argv[1])
number = re.search("= (.*)\(0x", objsizeStr)
size = int(number.group(1))
if size > 10000:
print sys.argv[1], size
and use it within your loop:
0:009> .foreach (res {!dumpheap -short -min 2000}) { !py c:\tmp\size.py ${res}}
00000087c6041fe8 10160
00000087d6021018 37248
00000087d6023658 27360
00000087d6025658 54488
00000087d6029638 53680
Note how the size of !objsize
differs from that of !dumpheap
. Just for cross-checking:
0:009> !objsize 00000087d6023658
sizeof(00000087d6023658) = 27360 (0x6ae0) bytes (System.Object[])
See also this answer on how to improve the script using expr()
so that you can pass expressions etc. The way I did it now outputs the size in decimal, but that's not explicit. Maybe you want to output a 0n
prefix to make it clear.