поиск объектов размером больше порога

Один из классов имеет много объектов, присутствующих в куче .NET, что было обнаружено с помощью следующей команды sos.

!dumpheap -stat  -type MyClass
Statistics:
              MT    Count    TotalSize    Class Name
00007ff8e6253494     1700     164123  MyNameSpace.MyClass

Мне нужно найти экземпляры тех объектов, размер которых ObjSize превышает 5 МБ. Я знаю, что могу перечислить objsize всех 1700 экземпляров MyClass, используя следующее.

.foreach (res {!DumpHeap -short -MT 00007ff8e6253494 }) {.if ( (!objsize res) > 41943040) {.echo res; !objsize res}}

С приведенным выше сценарием я не получаю никаких результатов, хотя есть экземпляры объектов размером более 5 МБ. Я думаю, что проблема может быть в том, что вывод objsize выглядит следующим образом

20288 (0x4f40) bytes

Это строка, которая затрудняет сравнение с любым порогом. Как я могу заставить этот скрипт отображать только объекты, размер которых превышает 5 МБ?


person BKS    schedule 19.10.2016    source источник
comment
Я удалил свой ответ, так как не позаботился опубликовать решение, эквивалентное !objsize.   -  person Steve Johnson    schedule 20.10.2016


Ответы (2)


Создание сложных сценариев в WinDbg весьма подвержено ошибкам. В таких ситуациях я переключаюсь на PyKd, расширение WinDbg, использующее Python.

Далее я расскажу только о недостающей части вашей головоломки, а именно о частях, которые не работают:

.if ( (!objsize res) > 41943040) {.echo res; !objsize res}

Вот моя отправная точка:

0:009> !dumpheap -min 2000
         Address               MT     Size
00000087c6041fe8 000007f81ea5f058    10158     
00000087d6021018 000007f81ea3f1b8     8736     
00000087d6023658 000007f81ea3f1b8     8192     
00000087d6025658 000007f81ea3f1b8    16352     
00000087d6029638 000007f81ea3f1b8    32672  

Вы можете написать такой скрипт (без обработки ошибок!)

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

и используйте его в своем цикле:

0:009> .foreach (res {!dumpheap -short -min 2000}) { !py c:\tmp\size.py ${res}}
00000087c6041fe8 10160
00000087d6021018 37248
00000087d6023658 27360
00000087d6025658 54488
00000087d6029638 53680

Обратите внимание, как размер !objsize отличается от размера !dumpheap. Просто для перепроверки:

0:009> !objsize 00000087d6023658
sizeof(00000087d6023658) = 27360 (0x6ae0) bytes (System.Object[])

См. также этот ответ о том, как улучшить скрипт с помощью expr(), чтобы вы могли передавать выражения и т. д. Как я это сделал сейчас выводит размер в десятичном виде, но это не явно. Возможно, вы хотите вывести префикс 0n, чтобы было понятно.

person Thomas Weller    schedule 20.10.2016
comment
Хорошая точка зрения. Я включу его, однако здесь я спрашиваю, как сравнить возвращаемое значение objsize, содержащее размер в десятичном, шестнадцатеричном формате и единице (байтах) ), с пороговым значением. - person paul deter; 20.10.2016

а также Стив прокомментировал !dumpeap принимает минимальный и максимальный параметры, и с ними должно быть возможно сделать это изначально

0:004> !DumpHeap -type System.String -stat

Statistics:
      MT    Count    TotalSize Class Name
6588199c        1           12 System.Collectionsxxxxx
65454aec        1           48 System.Collectionsxxxxx
65881aa8        1           60 System.Collectionsxxxxx
6587e388       17          596 System.String[]
6587d834      168         5300 System.String
Total 188 objects

0:004> !DumpHeap -type System.String -stat -min 0n64 -max 0n100

Statistics:
      MT    Count    TotalSize Class Name
6587e388        3          212 System.String[]
6587d834        9          684 System.String
Total 12 objects

0:004> !DumpHeap -type System.String -min 0n64 -max 0n100

 Address       MT     Size
01781280 6587d834       76     
01781354 6587d834       78     
01781478 6587e388       84     
017816d8 6587d834       64     
01781998 6587d834       78     
017819e8 6587d834       70     
01781a30 6587d834       82     
01782974 6587d834       78     
01782a6c 6587d834       90     
01782c7c 6587d834       68     
01783720 6587e388       64     
01783760 6587e388       64     

Statistics:
      MT    Count    TotalSize Class Name
6587e388        3          212 System.String[]
6587d834        9          684 System.String
Total 12 objects

манипулируя max,min, мы можем точно настроить только один или два объекта
пример, когда у нас есть 1 дополнительный объект на верхней стороне и 2 дополнительных объекта на нижней стороне
из вывода, предшествующего этому (15 объектов против 12 объектов)

0:004> !DumpHeap -type System.String -min 0n62 -max 0n106

 Address       MT     Size
01781280 6587d834       76     
01781354 6587d834       78     
017813e8 6587d834       62     
01781478 6587e388       84     
017816d8 6587d834       64     
01781898 6587d834      106     
01781998 6587d834       78     
017819e8 6587d834       70     
01781a30 6587d834       82     
01782974 6587d834       78     
01782a6c 6587d834       90     
01782c7c 6587d834       68     
01783720 6587e388       64     
01783760 6587e388       64     
01783e4c 6587d834       62     

Statistics:
      MT    Count    TotalSize Class Name
6587e388        3          212 System.String[]
6587d834       12          914 System.String
Total 15 objects

если по какой-то причине вам нужен адрес и размер, вы всегда можете это сделать

0:004> .shell -ci "!DumpHeap -type System.String -min 0n62 -max 0n106" awk "{print $1, $3}"

Address Size
01781280 76
01781354 78
017813e8 62
01781478 84
017816d8 64
01781898 106
01781998 78
017819e8 70
01781a30 82
01782974 78
01782a6c 90
01782c7c 68
01783720 64
01783760 64
01783e4c 62
person blabb    schedule 21.10.2016
comment
Позже Стив удалил свой ответ, потому что dumpheap не предоставляет инклюзивный размер, тогда как, исходя из вопроса, требуется инклюзивный размер объекта. - person BKS; 21.10.2016
comment
Я не уверен, стал бы я вызывать awk по умолчанию - person Thomas Weller; 22.10.2016
comment
Конечно, есть расширение клона awk iirc mex ???? - person blabb; 23.10.2016