4

我正在基于 Freescale MX51 的开发板 Linux 2.6.35 上开发一个 GUI 繁重的 C++ 应用程序。我想执行堆分析。

不幸的是,我发现的所有堆分析工具要么过于侵入,要么表面上无法在 ARM 上运行。我尝试过的具体工具:

  • Valgrind Massif:由于平台的 CPU 很弱,在我的平台上无法使用。Massif 引入的 80% CPU 时间开销在我的应用程序中导致了一系列无法​​弥补的问题。
  • gperftools (以前的谷歌性能工具)tcmalloc:除了堆分析器,这个相当非侵入性的、基于库的libc malloc()替换的所有功能都适用于我的目标换句话说,线程缓存分配器有效,但探查器无效。我将在下面为任何好奇的人解释分析器的故障模式。

谁能推荐一套替代工具来在 ARM 平台上执行 C++ 堆分析?理想的输出最终将是一个有向分配图,类似于 gperftools 的 tcmalloc 输出。低资源利用率是必须的——我的平台是高度资源受限的。


gperftools 的 tcmalloc 的故障模式解释:

我只为那些好奇的人提供这些信息;我不期待回应。我在下面看到类似于 gperftools 的问题 #407 的内容,除了在 ARM 而不是 x86 上。具体来说,我总是收到“未找到挂钩分配器框架,返回空跟踪”的消息。我花了一些时间调试这个问题,似乎在动态链接 tcmalloc 库时,我的应用程序和动态库之间的边界处的帧指针为空 - 堆栈不能在调用“上方”进入动态库。

gperftools 问题 #407:https ://github.com/gperftools/gperftools/issues/410

stackoverflow 用户在 ARM 上看到类似问题:ARM上的共享库中缺少帧

4

1 回答 1

2

堆。有很多方法可以做到,但我只遇到了 3 种在嵌入式领域很重要的主要类型:

  1. 链表堆。每个分配都在“已使用”列表中进行跟踪。一旦被释放,它们就会被放入“空闲”列表中。在释放时,相邻的空闲内存块被“连接”成更大的块。Allocs 可以是任意大小。每个 alloc 和 free 都是一个 O(N) 操作,因为它必须遍历空闲列表才能为您提供一块内存,并将空闲块分解为接近您要求的大小,同时将剩余块留在空闲列表中。由于每个分配的开销不断增加,因此该系统不能在较小的系统上单独使用。如果不采取措施将其最小化,这也会随着时间的推移导致内存碎片。

  2. 固定大小(单位)的堆。您将堆分成相同大小(较小)的部分。这会稍微浪费内存,具体取决于块有多大(以及您创建了多少不同大小的固定分配器堆),但 alloc 和 free 都是 O(1) 时间操作。没有搜索,没有加入。这种风格通常与第一种风格结合用于“小对象分配”,因为我使用过的引擎有 95% 的分配低于设定的大小(比如 256 字节)。这样,您可以将单元堆用于小型分配,以实现极快的速度和最小的内存损失,同时将列表堆用于较大的分配。也没有外部内存碎片。

  3. 可重定位内存堆。你不会给出指向内存的指针,而是句柄。这样,在幕后,您可以在需要时更改内存指针以删除碎片或其他任何东西。高开销。@$$ 商很痛苦,因为它很容易被滥用并得到悬空指针。还为每个内存取消引用增加了开销。但是想提一下。

有一些基本的模式。您可以在野外找到各种使用它们的库,并且还内置了分配数量、碎片和其他有用统计信息的统计信息。自己动手也并不难,尽管除了满足好奇心之外,我不推荐它,因为没有工作的 malloc 进行调试确实很痛苦。添加线程支持也非常简单,但同样,下载现成的解决方案是更好的选择。

以上信息适用于所有平台,无论是 ARM 还是其他平台,尽管我的大部分经验都是在低级 ARM 上进行的,因此以上信息已针对您的平台进行了实战测试。希望这可以帮助!

于 2012-07-17T16:54:47.177 回答