C语言 为什么 malloc 消耗那么多内存

  • 本文关键字:内存 malloc 语言 c malloc
  • 更新时间 :
  • 英文 :


我有一个项目,我做了很多malloc。我发现内存使用量远远大于数据本身。如果我使用 valgrind 并放置 100 MB 数据分配的内存为 500 MB。数据块的大小不同,每个 20-40 字节。以下是执行类似操作的最小程序,但具有相同大小的块。

它分配了大约 43 MB,但瓦尔格林德地块显示 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 bytesn", 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 memoryn");
            return 1;
        }
        memset(node->payload, 0, BUFFER_SIZE);
        node = node->next;
    }
    printf("donen");
    return 0;
}

首先,开销。malloc结构中有一个小开销。我认为每malloc大约 8 个字节.此外(部分是为了对齐,部分是为了实用性,部分是为了尽量减少下面的影响),内存分配的大小将四舍五入到2的小幂的倍数。

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

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

相关内容

  • 没有找到相关文章

最新更新