内存碎片化分析工具

20

有没有好的内存碎片分析工具?最好是Linux GCC版本。因为Valgrind无法分析使用自定义malloc/free函数的程序。

谢谢, 安德鲁


你可以使用 gdb 或其他调试器。 - Chris Lutz
2
使用gdb遍历并生成整个内存缓冲区的分析报告是不可行的,因为它管理的malloc内存分配器。 - nos
4个回答

5
我会从mtrace开始。当你有一个跟踪时,glibc附带了一个perl脚本mtrace(1),用于查找泄漏。然而,跟踪格式易于理解,因此将其转化为碎片分析应该是一个直截了当的过程。

4

恐怕答案是Valgrind。

你可以使用Valgrind扩展来告诉Valgrind哪些函数用于分配以及如何使用它(因此需要修改和重新编译应用程序,但如果您没有进行调试,则更改会编译为noops),详细信息在Valgrind手册中 Memory pools: working with custom allocators

完成后,您将拥有两个工具,可允许您诊断堆使用情况:massif和DHAT(快速提醒,Valgrind是一组工具,它只运行我们都知道和喜欢的Memcheck作为默认值)。

Massif "是一个堆分析器。它测量程序使用了多少堆内存。这包括有用空间和为了簿记和对齐目的而分配的额外字节的大小。它还可以测量程序的堆栈大小,尽管默认情况下不会这样做。"

它可以创建“图形”,因此它有点像图形化:

19.63^                                               ###                      
     |                                               #                        
     |                                               #  ::                    
     |                                               #  : :::                 
     |                                      :::::::::#  : :  ::               
     |                                      :        #  : :  : ::             
     |                                      :        #  : :  : : :::          
     |                                      :        #  : :  : : :  ::        
     |                            :::::::::::        #  : :  : : :  : :::     
     |                            :         :        #  : :  : : :  : :  ::   
     |                        :::::         :        #  : :  : : :  : :  : :: 
     |                     @@@:   :         :        #  : :  : : :  : :  : : @
     |                   ::@  :   :         :        #  : :  : : :  : :  : : @
     |                :::: @  :   :         :        #  : :  : : :  : :  : : @
     |              :::  : @  :   :         :        #  : :  : : :  : :  : : @
     |            ::: :  : @  :   :         :        #  : :  : : :  : :  : : @
     |         :::: : :  : @  :   :         :        #  : :  : : :  : :  : : @
     |       :::  : : :  : @  :   :         :        #  : :  : : :  : :  : : @
     |    :::: :  : : :  : @  :   :         :        #  : :  : : :  : :  : : @
     |  :::  : :  : : :  : @  :   :         :        #  : :  : : :  : :  : : @
   0 +----------------------------------------------------------------------->KB     0                                                                   29.48
快照数量:25 详细快照:[9、14(峰值)、24]
更重要的是,有一个Massif Visualizer可以生成非常漂亮的图形。 DHAT允许您诊断应用程序如何使用其堆,哪些部分短命,哪些在整个程序的生命周期中保留,但仅在开始时使用等等。不幸的是,它没有任何漂亮的图表或图形工具与之配套,输出纯文本。幸运的是,您可以告诉它要获取多少数据以及如何排序,因此并不像听起来那么糟糕。

1

我很难理解任何工具如何理解您自定义内存管理的段数据结构。您可能能够获得繁忙分布(钩入malloc/free),但空闲分布(本质上是碎片)似乎不确定。

那么,为什么不向您的自定义内存管理器添加繁忙/空闲统计信息/直方图呢?如果将bin索引按比例设置为log2(size),则保持这些统计数据的O(1)。当您拆分和合并时,您知道大小并且可以通过直接查找使用与log2(size)成比例的索引找到bin

例如,直方图bin间隔

[2^n,2^(n+1) ) ...

(例如,如果您想要更细的bin,请使用基于平方根2(size)的对数,这可以在x86上使用4个整数指令计算[位扫描,比较,设置,添加])

另一组合理的bin大小是以下开放间隔

[2^n, 2^n+2^(n-1) ),[2^n+2^(n-1),2^(n+1) )...

同样易于计算[位扫描,移位,和,添加])


他没有提到自定义分配器。有人可能编写了一个工具,可以遍历Linux上glibc分配器的内部结构,这并不是那么牵强的想法。 - nos
那么,“自定义”在“自定义malloc/free函数”中是什么意思? - pgast
4
“custom”指的是valgrind,将valgrind用作度量malloc碎片化并不明智,因为valgrind会替换默认的分配器(你需要测量真实的分配器,而不是valgrind钩入的分配器)。 - nos

0

nedmalloc是一个非常好的自定义分配器,附带源代码,经过优化以避免碎片化。

我会将其插入,并开始查看其内部日志记录的碎片统计信息。


nedmalloc看起来是加速程序的好方法,但如果不经过大量工作,它就无法解决碎片化分析问题。感谢您提供的信息,我正在认真考虑转换到它。 - Andrew
这个想法是,a) nedmalloc 能够很好地处理碎片化问题,因此它不是一个大问题,b) 它具有内置的调整和源代码,因此您可以使用比 mtrace 更详细的内省自己的分析。 - Justicle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接