【问题标题】:Memory Fragmentation Profiler内存碎片分析器
【发布时间】:2010-11-26 02:02:45
【问题描述】:

有没有好的内存碎片分析器? (linux gcc 版本会很好)。 Valgrind 无法对此进行分析,因为它使用了自定义的 malloc/free 函数。

谢谢, 安德鲁

【问题讨论】:

  • 您可以使用gdb 或其他调试器。
  • 使用 gdb 遍历并生成管理 malloc 的整个内存缓冲区的配置文件是不可行的。

标签: c++ c memory-management heap-fragmentation


【解决方案1】:

我将从mtrace 开始。当您进行跟踪时,glibc 会附带一个 perl 脚本 mtrace(1) 来查找泄漏。但是trace格式很容易理解,所以应该直接处理成碎片分析。

【讨论】:

    【解决方案2】:

    恐怕答案 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 允许您诊断应用程序如何准确地使用它的堆,哪些部分是短暂的,哪些部分会在整个程序的生命周期中保留,但仅在开始时使用,等等。不幸的是,它没有任何漂亮的图表或与之配套的图形工具,输出是纯文本。值得庆幸的是,您可以告诉它您想要获取多少数据以及如何对其进行排序,这样它就不会像听起来那么糟糕。

    【讨论】:

      【解决方案3】:

      我很难理解您可能找到的任何工具如何理解您的自定义内存管理的分段数据结构。您可能能够获得繁忙的发行版(挂钩到 malloc/free),但免费发行版(本质上是碎片)似乎悬而未决。

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

      例如直方图 bin 间隔

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

      (例如,如果您想要更精细的 bin,请使用 log base square root 2(size) 可以用x86上的4个整数指令计算[位扫描,比较,设置,添加])

      要使用的另一组合理的 bin 大小是以下开放区间

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

      再次容易计算[位扫描,移位,和,加])

      【讨论】:

      • 他没有提到自定义分配器。有人(例如)并不是那么牵强。写了一个工具,可以在 linux 上遍历 glibc 分配器的内部结构。
      • 那么“自定义 malloc/free 函数”中的“自定义”是什么意思?
      • 'custom' 指的是 valgrind - valgrind 测量 malloc 碎片是愚蠢的,因为 valgrind 替换了默认分配器(你想测量真正的分配器,而不是挂钩的那个 valgrind)
      【解决方案4】:

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

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

      【讨论】:

      • nedmalloc 看起来是加快程序速度的好方法,但如果没有大量工作,它就无法解决碎片分析问题。感谢您提供的信息,我正在认真考虑改用它。
      • 这个想法是 a) nedmalloc 可以很好地处理碎片,所以问题不大,b) 它内置了调优和源代码,因此您可以通过比类似 mtrace 的东西。
      猜你喜欢
      • 2010-11-18
      • 2013-08-14
      • 2012-04-03
      • 2010-10-26
      • 1970-01-01
      • 2018-09-25
      • 2012-12-11
      • 2011-01-17
      • 2020-02-15
      相关资源
      最近更新 更多