gpt4 book ai didi

c++ - windows故障转储文件详细内存使用分析?

转载 作者:IT老高 更新时间:2023-10-28 21:47:49 27 4
gpt4 key购买 nike

我们收到了来自客户的 native (完整)故障转储文件。在 Visual Studio (2005) 调试器中打开它显示我们遇到了由试图分配 ~10MB block 的 realloc 调用引起的崩溃。转储文件异常大(1.5 GB - 通常它们更像 500 MB)。

因此,我们得出结论,我们存在内存“泄漏”或失控分配,它们要么完全耗尽了进程的内存,要么至少将其碎片化到足以导致重新分配失败的程度。 (请注意,此 realloc 用于分配日志缓冲区的操作,我们并不惊讶它在这里失败,因为除了一些非常大且不可更改的缓冲区之外,一次性 10MB 将是我们所做的更大分配之一 - - 问题本身可能与此特定分配无关。)

编辑:在下面与 Lex Li 的评论交流后,我应该补充:这对我们来说是不可复制的(目前)。这只是一个客户转储,清楚地显示出失控的内存消耗。

主要问题:

现在我们有了一个转储文件,但是我们如何才能找到导致内存使用过多的原因呢?

到目前为止我们做了什么:

我们使用了DebugDiag tool分析转储文件(所谓的内存压力分析器),这是我们得到的:

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 或任何其他工具的任何提示都可以真正提供帮助!另外,如果您不同意我上面的任何分析,请告诉我们!谢谢!

最佳答案

你可以:

  • 查看这些 336 字节的 block ,看看内容是否告诉您有关分配它们的任何信息。为此,我通常使用windbg。首先运行命令 !heap -stat -h 0x01040000,它会给出 block 的大小,然后将这个 size 传递给 !heap -flt s size 将列出该大小的所有 block 。然后,您可以使用任何显示内存的命令(如 dc)查看该 block 。
  • 您无法重现该问题,但您可以查看另一个转储文件,该转储文件分配了该大小的 block 。首先使用 gflags.exe 实用程序 (gflags -i your.exe +ust) 激活堆栈回溯功能。然后运行您的应用程序,获取转储文件,并使用 !heap -flt s 列出 block 。然后命令 !heap -p -a blockaddress 将转储分配 block 的函数堆栈。

关于c++ - windows故障转储文件详细内存使用分析?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4735113/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com