Детальный анализ использования памяти в файле аварийного дампа windows?

Мы получили от клиента нативный (полный) файл дампа сбоя. Открытие его в отладчике Visual Studio (2005) показало, что у нас произошел сбой, вызванный вызовом realloc, который пытался выделить блок размером ~10MB. Файл дампа был необычно большим (1,5 ГБ - обычно они больше 500 МБ).

Поэтому мы пришли к выводу, что у нас есть "утечка" памяти или беглые выделения, которые либо полностью исчерпали память процесса, либо, по крайней мере, фрагментировали ее достаточно сильно, чтобы перераспределение не сработало. (Обратите внимание, что это перераспределение было выполнено для операции, которая выделяла буфер логирования, и мы не удивлены, что оно не сработало, потому что 10 МБ за один раз было бы одним из больших выделений, которые мы делаем, за исключением некоторых очень больших довольно неизменных буферов - сама проблема, скорее всего, не связана с этим конкретным выделением)

Edit: После обмена комментариями с Lex Li ниже, я должен добавить: Это не воспроизводимо для нас (на данный момент). Это всего лишь один клиентский дамп, явно демонстрирующий бешеное потребление памяти.

Главный вопрос:

Теперь у нас есть файл дампа, но как мы можем определить, что вызвало чрезмерное использование памяти?

Что мы уже сделали:

Мы использовали инструмент DebugDiag для анализа файла дампа (так называемый Memory Pressure Analyzer), и вот что мы получили:

Report for DumpFM...dmp

Virtual Memory Summary
----------------------
Size of largest free VM block   62,23 MBytes 
Free memory fragmentation       81,30% 
Free Memory                     332,87 MBytes   (16,25% of Total Memory) 
Reserved Memory                 0 Bytes   (0,00% of Total Memory) 
Committed Memory                1,67 GBytes   (83,75% of Total Memory) 
Total Memory                    2,00 GBytes 
Largest free block at           0x00000000`04bc4000 

Loaded Module Summary
---------------------
Number of Modules       114 Modules 
Total reserved memory   0 Bytes 
Total committed memory  3,33 MBytes 

Thread Summary
--------------
Number of Threads       56 Thread(s) 
Total reserved memory   0 Bytes 
Total committed memory  652,00 KBytes 

Это было просто для того, чтобы получить немного контекста. Что, на мой взгляд, интереснее:

Heap Summary
------------
Number of heaps         26 Heaps 
Total reserved memory   1,64 GBytes 
Total committed memory  1,61 GBytes 

Top 10 heaps by reserved memory
-------------------------------
0x01040000           1,55 GBytes        
0x00150000           64,06 MBytes        
0x010d0000           15,31 MBytes        
...

Top 10 heaps by committed memory
--------------------------------                              
0x01040000       1,54 GBytes 
0x00150000       55,17 MBytes 
0x010d0000       6,25 MBytes  
...            

Теперь, глядя на кучу 0x01040000 (1,5 ГБ), мы видим:

Heap 5 - 0x01040000 
-------------------
Heap Name          msvcr80!_crtheap 
Heap Description   This heap is used by msvcr80 
Reserved memory      1,55 GBytes 
Committed memory     1,54 GBytes (99,46% of reserved)  
Uncommitted memory   8,61 MBytes (0,54% of reserved)  
Number of heap segments             39 segments 
Number of uncommitted ranges        41 range(s) 
Size of largest uncommitted range   8,33 MBytes 
Calculated heap fragmentation       3,27% 

Segment Information
-------------------
Base Address | Reserved Size   | Committed Size  | Uncommitted Size | Number of uncommitted ranges | Largest uncommitted block | Calculated heap fragmentation 
0x01040640        64,00 KBytes      64,00 KBytes   0 Bytes            0                              0 Bytes                     0,00% 
0x01350000     1.024,00 KBytes   1.024,00 KBytes   0 Bytes            0                              0 Bytes                     0,00% 
0x02850000     2,00 MBytes       2,00 MBytes       0 Bytes            0                              0 Bytes                     0,00% 
...

Что это вообще за Segment Information?

Глядя на перечисленные выделения:

Top 5 allocations by size
-------------------------
Allocation Size - 336          1,18 GBytes     
Allocation Size - 1120004      121,77 MBytes    
...

Top 5 allocations by count
--------------------------
Allocation Size - 336    3760923 allocation(s) 
Allocation Size - 32     1223794 allocation(s)  
...

Мы видим, что, очевидно, куча MSVCR80 содержит 3.760.923 распределений по 336 байт. Это ясно показывает, что мы зачистили память множеством небольших выделений, но как мы можем получить больше информации о том, откуда взялись эти выделения??

Если бы мы могли каким-то образом сделать выборку некоторых из этих адресов выделений и затем проверить, где в образе процесса эти адреса используются, тогда - предполагая, что большая часть этих выделений ответственна за нашу "утечку" - мы могли бы выяснить, откуда взялись эти убегающие выделения.

К сожалению, на данный момент у меня нет идей, как получить больше информации из дампа.

Как я могу осмотреть эту кучу, чтобы увидеть некоторые из "336" адресов выделения?

Как я могу найти в дампе эти адреса и как я могу узнать, какая переменная-указатель (если таковая имеется) в дампе держится за эти адреса?

Любые советы по использованию DebugDiag, WinDbg или любого другого инструмента могут очень помочь! Также, если вы не согласны с каким-либо моим анализом выше, дайте нам знать! Спасибо!

21
задан Martin Ba 26 January 2011 в 07:39
поделиться