为什么malloc消耗了那么多内存?

时间:2015-01-21 18:48:28

标签: c malloc

我有一个项目,我做了很多malloc's。我发现内存使用量远远大于数据本身。如果我使用valgrind并将100 MB数据分配内存为500 MB。数据块大小不同,每个大小为20-40个字节。这是最小的程序,做类似的事情,但与相同大小的块。

它分配大约43 MB,但valgrind massif显示53 MB。

如果使用jemalloc运行,则顶部显示47 MB​​。

目前所有块都有不同的大小,我不能使用数组等。

我可以使用malloc的一些设置,或者如果有不同的类似malloc的命令我可以用来最小化浪费的内存?

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define BUFFER_SIZE 39
#define MANY        1000000LU

typedef struct _list{
    void    *next;
    char    payload[BUFFER_SIZE];
}list;


int main(){
    list root;

    printf("Allocating %lu chunks %zu bytes each, equals to %lu bytes\n", MANY, sizeof(list), MANY * sizeof(list));

    list *node = & root;
    unsigned long int i;
    for(i = 0; i < MANY; i++){
        node->next = malloc(sizeof(list));

        if (node->next == NULL){
            printf("Out of memory\n");
            return 1;
        }

        memset(node->payload, 0, BUFFER_SIZE);

        node = node->next;
    }

    printf("done\n");

    return 0;
}

2 个答案:

答案 0 :(得分:0)

首先,开销。 malloc结构中的开销很小。我认为每malloc大约8个字节。另外(部分用于对齐,部分用于实用,部分用于最小化下面的效果),内存分配将被大小四舍五入为2的小功率的倍数。

其次,碎片化。假设您分配了3 900个字节块,A,B和C,并且分配器选择按顺序分配它们。接下来,假设B被释放。由于孔小于操作系统页面大小,因此“孔”小于&#39; B处于无法返回操作系统的状态。如果使用malloc的所有后续分配都大于900字节,则永远不会填充漏洞 - 即浪费掉它。如果(比方说)出现600字节的分配,可能被放置在漏洞中,但那将留下300字节的漏洞。在这种情况下,没有分配器能够完美地运行。

答案 1 :(得分:0)

在现代操作系统上,malloc的常见实现将请求大块虚拟内存空间并将其拆分为分配池。然后它将从这些池中分配出内存,因为它有自己的优化参数(无论是通过大小,线程,片段缩减等)。一种天真的记忆观点认为这是浪费。但是,虚拟内存不一定由物理页面支持,直到它被使用,当操作系统将根据需要回填它的映射(类似于分页的工作方式,但具有匿名内存支持)。因此,您查看的进程使用的数字不一定是正在使用的实际内存,只需分配等待使用的VM空间。