お客様からネイティブ(完全)クラッシュダンプファイルを受け取りました。Visual Studio(2005)デバッガーで開くと、最大10MBのブロックを割り当てようとしたrealloc呼び出しが原因でクラッシュが発生したことがわかります。ダンプファイルは異常に大きかった(1.5GB-通常は500MB程度)。
したがって、プロセスのメモリを完全に使い果たすか、少なくとも再割り当てが失敗するのに十分なほど大幅にフラグメント化されたメモリ「リーク」または暴走割り当てがあると結論付けます。(このreallocは、ロギングバッファーを割り当てた操作用であり、ここで失敗したことは驚くことではありません。これは、一度に10MBが、非常に大きなかなり変更できないバッファーとは別に、より大きな割り当ての1つになるためです。問題それ自体は、この特定の割り当てとは関係がない可能性があります。)
編集:以下のLex Liとのコメント交換の後、追加する必要があります:これは(現時点では)再現できません。これは、暴走したメモリ消費を明確に示している1つの顧客ダンプです。
主な質問:
これでダンプファイルができましたが、過剰なメモリ使用量の原因をどのように特定できますか?
これまでに行ったこと:
DebugDiagツールを使用してダンプファイル(いわゆるメモリ圧力アナライザー)を分析しました。取得したものは次のとおりです。
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 GB)を見ると、次のようになります。
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%
...
とにかくこのセグメント情報は何ですか?
リストされている割り当てを見てください:
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ヒープは336バイトで3.760.923の割り当てを保持していることがわかります。これは、私たちがたくさんの小さな割り当てでメモリをモップアップしたことをかなり明確にしていますが、これらの割り当てがどこから来たのかに関するより多くの情報をどのように得ることができますか?
どういうわけかこれらの割り当てアドレスの一部をサンプリングし、プロセスイメージのどこでこれらのアドレスが使用されているかを確認できれば、これらの割り当ての大部分が「リーク」の原因であると仮定すると、どこにあるかを見つけることができます。これらの暴走した割り当てはから来ました。
残念ながら、現時点では、ダンプからより多くの情報を取得する方法がわかりません。
このヒープを調べて、「336」の割り当てアドレスのいくつかを確認するにはどうすればよいですか?
ダンプでこれらのアドレスを検索するにはどうすればよいですか。また、ダンプ内のどのポインター変数(存在する場合)がこれらのアドレスに保持されているかを確認するにはどうすればよいですか?
DebugDiag、WinDbg、またはその他のツールの使用に関するヒントは、本当に役に立ちます。また、上記の私の分析のいずれかに同意できない場合は、お知らせください。ありがとう!