c - 为什么 malloc 会消耗那么多内存?

标签 c malloc

我有一个项目,其中我做了很多 malloc。我发现内存使用量比数据本身大得多。如果我使用 valgrind 并放入 100 MB 数据,则分配的内存为 500 MB。数据 block 大小不同,每个 20-40 字节。这是做类似事情的最小程序,但具有相同大小的 block 。

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

如果使用 jemalloc 运行,top 也会显示 47 MB​​。

目前所有 block 的大小都不同,我不能使用数组或其他东西。

是否有一些我可以使用的 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;
}

最佳答案

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

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

关于c - 为什么 malloc 会消耗那么多内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28074587/

相关文章:

linux - mallinfo 的 64 位替代品?

c - 如何在不使用循环和默认转换的情况下一一打印联系人号码?

c++ - 使用 %s 格式化时 # 的作用是什么

c - 具有多个子节点和两个指向左右的节点的二叉搜索树

c - 二维数组分配的段错误

c - malloc 清零内存?

c++ - C/C++ 与 Python 之间交换值的应用程序设计

c - 从C中的BST中删除节点

objective-c - C 和 Objective-C - 释放无符号字符指针的正确方法

c - 在堆中分配函数的返回值