3

我的程序使用大量内存。这就是 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 小时工作,并且可以处理大量数据。

4

3 回答 3

3

根据文档,“额外堆”字节如下:

在该点分配的额外堆字节数。这反映了分配的字节数超过了程序要求的数量。额外的堆字节有两个来源。

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

其次,分配器通常将请求的字节数四舍五入到更大的数字,通常是 8 或 16。这是确保块中的元素适当对齐所必需的。如果需要 N 个字节,Massif 会将 N 向上舍入为 --alignment 选项指定的值的最接近的倍数。

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

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

为了防止内存分配,基本上减少分配!尽可能使用堆栈空间(例如,不要不必要地使用新的),如果可能的话考虑化频繁分配的对象,这样你就不会一直分配内存。

于 2011-03-21T13:20:10.900 回答
3

你是否分配了很多非常小的对象——比如说,只有几个字节?每次分配都有一定的开销(因为,例如,free需要能够判断块有多大)。

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

如果要分配许多非常小的对象,则应考虑单独管理它们,而不是在堆上单独分配它们。如果你做得对,这在其他方面也可能会更好(例如,提高内存局部性)。

于 2011-03-21T13:24:10.803 回答
0

你可以做更少的分配更大的大小或调整堆 - 后者将是特定于实现的。

这不是碎片,只是当您要求说 7 个字节时,堆分配不少于 7 个字节- 可以说是 16 个字节,因此 9 个字节成为“额外”并且实际上被浪费了。这样做有多种原因 - 例如,为了保持对齐。

于 2011-03-21T13:19:49.393 回答