堆分析在ARM上的应用

4

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

不幸的是,我找到的所有堆分析工具都要么过于侵入性,要么在ARM上似乎无法工作。我尝试过的具体工具:

  • Valgrind Massif: 在我的平台上无法使用,因为该平台的CPU太弱。由Massif引入的80% CPU时间开销会导致我应用程序中出现无法补偿的一系列问题。
  • gperftools(前身为Google性能工具)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上遇到类似问题:Missing frames on shared libraries on ARM


4
哇,所以512MB是“高度资源受限的”... - Igor Skochinsky
回响着我从GBA/DS编程中的思维 :) - Michael Dorgan
1个回答

2
堆。有许多方法可以实现堆,但在嵌入式领域中只遇到了三种主要类型:
1. 链表堆。每个分配都在“已用”列表中跟踪。一旦释放,它们就会被放入“空闲”列表中。在释放时,相邻的空闲内存块将被“合并”成较大的块。分配可以是任意大小。每个分配和释放都是O(N)操作,因为它必须遍历空闲列表以提供一块内存,并将空闲块分解为接近您所请求的大小,同时将剩余块留在空闲列表中。由于每个分配的开销增加,这个系统不能单独在较小的系统上使用。如果不采取措施来最小化它,这也往往会导致内存碎片化。
2. 固定大小(单位)堆。你将堆分成相等大小(更小)的部分。这会浪费一些内存,具体取决于块的大小(以及你创建了多少个不同大小的固定分配器堆),但分配和释放都是O(1)时间操作。没有搜索,没有合并。这种风格通常与第一种风格结合在一起,用于“小对象分配”,因为我所使用的引擎中95%的分配都在一组大小以下(比如256字节)。这样,你可以使用单元堆进行小分配,获得巨大的速度和最小的内存损失,同时使用列表堆进行大分配。没有外部内存碎片。
3. 可重定位内存堆。你不会给出内存指针,而是句柄。这样,在幕后,你可以在需要时更改内存指针以消除碎片或其他问题。开销很高。痛苦的地方在于很容易滥用并在各处留下悬空指针。每个内存解引用也会增加开销。但还是想提一下。
以上是一些基本模式。你可以在野外找到各种库,它们使用这些模式,并且具有内置的统计信息,例如分配数量、碎片化和其他有用的统计信息。制作自己的库其实也不难,尽管我不建议在除了满足好奇心之外的任何情况下这样做,因为没有工作的malloc调试是非常痛苦的。添加线程支持也很简单,但再次下载现成的解决方案才是更好的选择。
上述信息适用于所有平台,包括ARM或其他平台,虽然我的大部分经验都是在低级ARM方面,所以上述信息已经在你的平台上进行了实战测试。希望这有所帮助!

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