为什么malloc会分配比我要求的更多的内存空间?

时间:2016-01-31 04:13:21

标签: c memory memory-management malloc valgrind

我发现malloc()分配的内存空间比我要求的多。

struct { void *ptr; int var; } msg;   // 16 bytes (checked by sizeof())

for (int i = 0; i < 100000000; i++)
    malloc(sizeof(msg));

如前面提到的代码,malloc()实际上为每个函数调用分配了32个字节(由top计算),但valgrind确实每个调用仅显示16个字节。

为什么malloc会分配比我要求更多的内存空间,以及如何强制malloc()不要浪费那么多内存空间?

令人惊讶的是,即使结构是24字节,它也会分配32个字节,所以我猜测内存空间是浪费的。我不确定malloc()是否应该分配32个字节的倍数。如果它是真的,那么就会浪费内存空间。

编辑:

我已经测试了其他情况。

+---------+---------------------------+
|    n    | memory usage of malloc(n) |
+---------+---------------------------+
|  1 ~ 24 |         32 bytes          |
+---------+---------------------------+
| 25 ~ 40 |         48 bytes          |
+---------+---------------------------+
| 41 ~ 56 |         64 bytes          |
+---------+---------------------------+

如果n不是16 * m + 8m∈ℕ,则内存未完全使用。由于n等于22时的内存对齐,浪费了一些内存空间,但当n等于16时,它仍应被视为浪费。在大多数平台上,最小内存访问单元的大小是4个字节或8个字节,那么为什么GCC实现每次增加选择16个字节。

3 个答案:

答案 0 :(得分:1)

malloc()calloc()等分配的任何额外内存(如果有)是系统的实现定义方面,而不是由C指定。

检查编译器的规范以确定原因。通常用于内存管理。

要强制使用其他分配方案,请重写malloc()或使用您自己的内存分配函数。

答案 1 :(得分:1)

ptmalloc 具有非常重要的运行时开销。 GNU C库使用基于dlmalloc的{​​{1}}(&#34; Doug Lea&#39;&#34;)。

堆上的内存被分配为&#34; chunk&#34;,8-byte对齐的数据结构,其中包含标头和可用内存。分配的内存对于块和使用标志的大小包含816 byte开销。未分配的块还存储指向可用空间区域中其他空闲块的指针,使得最小块大小24 bytes

未分配的内存分为&#34; bins&#34;大小相似,通过使用双链接的列表列表实现(指针存储在块内未分配的空间中)。

对于256 bytes以下的请求(&#34; smallbin&#34;请求),使用简单的两个最佳功能分配器。如果该bin中没有空闲块,则将下一个最高bin中的块拆分为两个。

您可以阅读更多相关信息here

答案 2 :(得分:0)

分配的多余字节,即开销是特定于实现的,实现中的存储器管理器分配内部跟踪/管理目的所需的内存。内存空间不被视为浪费。 你关注的是真实的,特别是如果你正在寻找数以百万计的小分配 - 这将导致大量的堆内存碎片,当然还有巨大的开销。所以我可以想到两个选项 - 编写堆分配器或更好地使用其他人编写/测试/共享的内存管理器 - 从Facebook的jemalloc或Google的tcmalloc开始 -