My problem is that dumpheap -stat
returns an awful lot of objects and I have no idea which ones are rooted and which ones are not.
Well, I can if I run the !mroot
or !refs
command on an individual address, but this approach does not scale very well to thousands of objects reported by dumpheap
.
For example, dumpheap -stat
contains the following line:
000007fef3d14088 74247 2375904 Microsoft.Internal.ReadLock
Wow, 74,247 instances. However, running
.logopen c:\tmp\2\log.txt;.foreach (entry {!dumpheap -type Microsoft.Internal.ReadLock -short}){!refs ${entry} -target};.logclose
reveals that each and every instance reported by DumpHeap
is actually unreclaimed garbage!
How I found that each and every instance is garbage is another problem. I had to extract all the NONE
strings to one file and all the Objects referencing
strings to another and then compared the number of lines in every file. Surely there is a better way :-(.
Anyway, I would like to know how to focus on the rooted objects only. Ideally, I would like to get the statistics as well as details on such objects.
Your loop over all objects is already great, just the !refs command needs to be replaced by something else which finds only rooted objects. My example uses Strings, because I don't have an application available using ReadLocks.
There are two possible outputs of the !refs command. A referenced object outputs e.g.
A garbage objects looks like this:
You're only interested in the address of the first line in case the second line contains the word "follows". Luckily, the address is equal to
${entry}
, so we actually don't need it. Otherwise you would be in the same trouble like I am.This brings me to this question about .if.
You can use .foreach again on the output of !refs. Let's have a look at this on a single object first:
This prints one word per line and we are interested only in the fifth, which means we can initially skip 4 items and then skip the rest, which gives us
For robustness purposes, let's use
/ps 99
.Next we need to check if this token equals follow, which is done by
And combine it all together:
In one line:
Of course you can replace .print by any other command which is helpful in your situation.
I hope you can adapt this sample to use ReadLock.