valgrind显示的额外堆程序内存消耗

时间:2011-03-21 13:07:55

标签: c linux heap valgrind memory-fragmentation

我的程序使用了大量内存。这是valgrind massif工具向我展示的:

--------------------------------------------------------------------------------
  n        time(i)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
--------------------------------------------------------------------------------
 28 38,531,086,036      760,235,208      143,002,822   617,232,386            0

正如您所看到的,额外部分比有用堆大几倍。

我该怎么做才能减少额外的记忆? 少花钱分配?

这就是所谓的内存碎片吗?

操作系统:Linux 2.6。程序用C语言编写。它应该工作24 \ 7并且它操作大量数据。

3 个答案:

答案 0 :(得分:3)

根据documentation,“extra-heap”字节如下:

  

额外堆字节数   在那时分配。这反映了   分配的字节数   超出了该计划的要求。   额外堆有两个来源   字节。

     

首先,每个堆块都有   与之关联的管理字节   它。确切的行政数量   字节取决于细节   分配器。默认情况下,Massif假定为8   每个块的字节数,可以从中看出   例子,但这个数字可以   通过--heap-admin选项更改。

     

其次,分配器经常围绕   要求更大的字节数   数字,通常是8或16.这是   需要确保元素   在块内适当地对齐。   如果要求N个字节,Massif   将N舍入到最接近的倍数   --alignment指定的值   选项。

这对我来说听起来不像是内存碎片。

内存碎片通常是由大量小分配引起的。最终在每个已分配内存单元之间存在小的间隙,然后很难为更大的分配获得连续的内存区域。

防止内存分配基本上减少了分配!尽可能使用堆栈空间(例如,不要不必要地使用new),如果可能,请考虑pooling经常分配的对象,这样就不会继续分配内存。

答案 1 :(得分:3)

你是否分配了很多极小的对象 - 比如几个字节?每次分配都会产生一定的开销(因为,例如,free需要能够分辨出块的大小。)

这有时被称为“内部碎片”,而不是“外部碎片”,其中存在一定数量的未分配内存,但您无法使用它,因为它被分割成太小而无法使用的块。 (malloc永远不会返回真正小块的另一个原因是因为这有助于减少外部碎片。)

如果 分配大量非常小的对象,则应考虑单独管理它们,而不是在堆上单独分配它们。如果你做得对,这在其他方面也可能更好(例如,改善记忆位置)。

答案 2 :(得分:0)

您可以减少更大规模的分配或调整堆 - 后者将是特定于实现的。

这不是碎片,只是当你要求说7个字节时,堆分配不少于7个字节 - 可以说是16个字节,所以9个字节变成“额外”并且实际上是浪费了。这是出于各种原因 - 例如,保持对齐。