我有一个项目,我做了很多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;
}
答案 0 :(得分:0)
首先,开销。 malloc
结构中的开销很小。我认为每malloc
大约8个字节。另外(部分用于对齐,部分用于实用,部分用于最小化下面的效果),内存分配将被大小四舍五入为2的小功率的倍数。
其次,碎片化。假设您分配了3 900个字节块,A,B和C,并且分配器选择按顺序分配它们。接下来,假设B被释放。由于孔小于操作系统页面大小,因此“孔”小于&#39; B处于无法返回操作系统的状态。如果使用malloc
的所有后续分配都大于900字节,则永远不会填充漏洞 - 即浪费掉它。如果(比方说)出现600字节的分配,可能被放置在漏洞中,但那将留下300字节的漏洞。在这种情况下,没有分配器能够完美地运行。
答案 1 :(得分:0)
在现代操作系统上,malloc
的常见实现将请求大块虚拟内存空间并将其拆分为分配池。然后它将从这些池中分配出内存,因为它有自己的优化参数(无论是通过大小,线程,片段缩减等)。一种天真的记忆观点认为这是浪费。但是,虚拟内存不一定由物理页面支持,直到它被使用,当操作系统将根据需要回填它的映射(类似于分页的工作方式,但具有匿名内存支持)。因此,您查看的进程使用的数字不一定是正在使用的实际内存,只需分配等待使用的VM空间。