14

所以我有这个分配 256 MB 内存的程序,在用户按下 ENTER 后,它会释放内存并终止。

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

int main(void) {
    char *p, s[2];

    p = malloc(256 * 1024 * 1024);
    if ( p == NULL) 
        exit(1);

    printf("Allocated"); 
    fgets(s, 2, stdin);
    free(p);
    return 0;
}

我多次运行该程序并将它们中的每一个都设置为后台,直到没有足够的内存可以分配。然而,这永远不会发生。我运行了一个 linuxtop命令,即使多次运行该程序,可用内存也从未减少近 256 MB。

但是,另一方面,如果我使用calloc而不是mallocthen 会有很大的不同:

p = calloc(256 * 1024 * 1024, 1);

现在,如果我运行程序并将其置于后台,然后重复,每次运行它时,可用内存都会减少 256 MB。为什么是这样?为什么不会malloc导致可用的空闲内存发生变化,但calloc会发生变化?

4

3 回答 3

27

malloc()使用内存。它分配它。

分配内存后,通过分配一些数据来使用它。

size_t Size = 256 * 1024 * 1024;
p = malloc(Size);
if (p != NULL) {
  memset(p, 123, Size);
}

一些平台实现malloc()的方式是在访问该字节(或更可能是一组字节或字节“页”中的一个字节)之前不会发生内存的物理消耗。

calloc()可能也可能不会真正使用内存。系统可以大量内存映射到相同的物理归零内存,至少在数据变得有趣之前是这样。请参阅 为什么 malloc+memset 比 calloc 慢?

于 2013-11-15T01:07:46.663 回答
13

内存可能并不真正可用,尤其是您在示例中没有做任何事情p,除了检查它是否为NULL. 来自man malloc

默认情况下,Linux 遵循乐观的内存分配策略。这意味着当malloc()返回 non-时NULL,不能保证内存确实可用。如果发现系统内存不足,OOM 杀手将杀死一个或多个进程。有关详细信息,请参阅/proc/sys/vm/overcommit_memory/proc/sys/vm/oom_adj中的描述proc(5),以及 Linux 内核源文件 Documentation /vm/overcommit-accounting

于 2013-11-15T01:10:00.093 回答
4

您系统上的calloc† 实际上通过清除内存来触及内存,并且在许多系统上,内存在被分配给它的进程触及之前并没有真正分配(因此“用完”)。因此,在你使用它之前,只是做malloc不会“使用”内存。

† 看评论

于 2013-11-15T01:09:11.600 回答