WinDbg не сообщает мне, где находится моя строка

Я пытаюсь ng, чтобы отследить, почему строка так долго хранится в моем приложении и занимает слишком много памяти. У меня есть служба Windows, которая работает регулярно.

Он считывает данные из базы данных (в форме DataSet), а затем выполняет некоторую обработку - все это управляется .NET.

Служба Windows запускается примерно каждые 5 минут, что делает некоторые перекрестные ссылки. Каждая строка DataSet не должна занимать больше секунды - худший случай!

На одном этапе байты личного пользования> 1.2 ГБ, хотя данные для обработки отсутствовали. Глобальных переменных нет, и вся обработка выполняется отдельными методами.

Я сделал снимок и обработал его с помощью WinDbg. Вот результаты:

0:000> !dumpheap -min 85000
 Address       MT     Size
02027f40 00166620   101432 Free
28411000 79330b24 536870936     
48c11000 79333594 226273040     
08411000 79330b24 452546504     
total 4 objects
Statistics:
      MT    Count    TotalSize Class Name
00166620        1       101432      Free
79333594        1    226273040 System.Byte[]
79330b24        2    989417440 System.String
Total 4 objects

Итак, мы хотим найти 2 строки, которые вызывают проблему:

0:000> !dumpheap -mt 79330b24  -min 85000
 Address       MT     Size
28411000 79330b24 536870936     
08411000 79330b24 452546504     
total 2 objects
Statistics:
      MT    Count    TotalSize Class Name
79330b24        2    989417440 System.String
Total 2 objects

Теперь я хочу выяснить, где находятся эти 2 строки, но когда я использую! Gcroot, он не возвращает любые результаты:

0:000> !gcroot 28411000 
Note: Roots found on stacks may be false positives. Run "!help gcroot" for
more info.
Scan Thread 0 OSTHread 2970
Scan Thread 2 OSTHread 2ab4
Scan Thread 3 OSTHread 12ac
Scan Thread 4 OSTHread 1394
Scan Thread 5 OSTHread 1b78
Scan Thread 8 OSTHread 1364
Scan Thread 9 OSTHread 226c
Scan Thread 10 OSTHread 1694
0:000> !gcroot 08411000 
Note: Roots found on stacks may be false positives. Run "!help gcroot" for
more info.
Scan Thread 0 OSTHread 2970
Scan Thread 2 OSTHread 2ab4
Scan Thread 3 OSTHread 12ac
Scan Thread 4 OSTHread 1394
Scan Thread 5 OSTHread 1b78
Scan Thread 8 OSTHread 1364
Scan Thread 9 OSTHread 226c
Scan Thread 10 OSTHread 1694

Я не понимаю, что я делаю неправильно или почему не удается найти корень строки. Я сделал! Do на нем, и там просто говорится, что строки не печатаются:

0:000> !do 28411000 
Name: System.String
MethodTable: 79330b24
EEClass: 790ed65c
Size: 536870930(0x20000012) bytes
 (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String: <String is invalid or too large to print>

Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
79332d70  4000096        4         System.Int32  0 instance 268435457 m_arrayLength
79332d70  4000097        8         System.Int32  0 instance 226273026 m_stringLength
79331804  4000098        c          System.Char  0 instance       57 m_firstChar
79330b24  4000099       10        System.String  0   shared   static Empty
    >> Domain:Value  00159f38:01021198 <<
79331754  400009a       14        System.Char[]  0   shared   static WhitespaceChars
    >> Domain:Value  00159f38:010217d4 <<

И

0:000> !do 08411000 
Name: System.String
MethodTable: 79330b24
EEClass: 790ed65c
Size: 452546502(0x1af94fc6) bytes
 (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String: <String is invalid or too large to print>

Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
79332d70  4000096        4         System.Int32  0 instance 226273243 m_arrayLength
79332d70  4000097        8         System.Int32  0 instance 226273242 m_stringLength
79331804  4000098        c          System.Char  0 instance       45 m_firstChar
79330b24  4000099       10        System.String  0   shared   static Empty
    >> Domain:Value  00159f38:01021198 <<
79331754  400009a       14        System.Char[]  0   shared   static WhitespaceChars
    >> Domain:Value  00159f38:010217d4 <<

Кто-нибудь может помочь, пожалуйста?

-

Обновление:

! Eeheap -gc

Number of GC Heaps: 1
generation 0 starts at 0x01175764
generation 1 starts at 0x011756dc
generation 2 starts at 0x01021000
ephemeral segment allocation context: none
 segment    begin allocated     size
01020000 01021000  0117b770 0x0015a770(1419120)
Large object heap starts at 0x02021000
 segment    begin allocated     size
02020000 02021000  02040d88 0x0001fd88(130440)
28410000 28411000  48411018 0x20000018(536870936)
48c10000 48c11000  563db710 0x0d7ca710(226273040)
08410000 08411000  233a5fc8 0x1af94fc8(452546504)
Total Size  0x488d9be8(1217240040)
------------------------------
GC Heap Size  0x488d9be8(1217240040)

Обновить 2: Я удалил ссылки на XML, поскольку эта конкретная программа не обрабатывает XML - моя проблема.


Обновление 3:

Вот результаты использования psscor2.dll

0:000> !heapstat -inclUnrooted
Heap     Gen0         Gen1         Gen2         LOH
Heap0    32780        68316        1324728      1217845888  

Free space:                                                 Percentage
Heap0    12           67212        59764        101640      SOH:  8% LOH:  0%

Unrooted objects:                                           Percentage
Heap0    2684         1104         757416       1217715448  SOH: 53% LOH: 99%
11
задан Dominic Zukiewicz 8 July 2010 в 14:04
поделиться

2 ответа

EDITED (Ооо, требуется еще кофе) Эти строки больше 85 000 байт, поэтому они будут находиться в куче больших объектов, которые редко собираются сборщиком мусора и не сжимаются (что приводит к фрагментации, особенно если вы: перераспределение большого количества короткоживущих крупных объектов).

То, что WinDbg сообщает вам, верно - у них нет корня, и они представляют собой мусор, но, поскольку они находятся в LOH, они могут не быть быстро очищены (если вообще).

Вам определенно нужно переосмыслить, как вы обрабатываете XML, обращать внимание на потоковую передачу данных, а не на загрузку / создание в памяти заранее.

7
ответ дан 3 December 2019 в 10:43
поделиться

Объекты в LOH будут собираться только при наличии нехватки памяти. GC будет собирать объекты в LOH только при выполнении полной коллекции.

В psscor2.dll (расширение для отладки управляемого кода) есть команда

!HeapStat [-inclUnrooted | -iu]

которая будет сбрасывать только действительные корни, по сравнению с !eeheap

1
ответ дан 3 December 2019 в 10:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: