简体   繁体   English

为什么malloc没有“用完”计算机上的内存?

[英]Why is malloc not “using up” the memory on my computer?

So I have this program that allocates 256 MB of memory, and after the user presses ENTER it frees the memory and terminates. 因此,我有一个分配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;
}

I ran this program multiple times and backgrounded each of them until there is no longer enough memory that can be allocated. 我多次运行了该程序并将它们分别作为背景,直到不再有足够的内存可以分配。 However, that never happens. 但是,那永远不会发生。 I ran a linux top command and even after running this program many times, the free memory never goes down by nearly as much as 256 MB. 我运行了linux top命令,即使多次运行该程序,可用内存也不会减少多达256 MB。

However, on the other hand, if I use calloc instead of malloc then there is a HUGE difference: 但是,另一方面,如果我使用calloc而不是malloc则存在巨大的差异:

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

Now if I run the program and background it, and repeat, every time I run it, the free memory goes down by 256 MB. 现在,如果我运行该程序并使其后台运行,然后重复执行,则每次运行它时,可用内存都会减少256 MB。 Why is this? 为什么是这样? Why does malloc not cause the available free memory to change, but calloc does? 为什么malloc不会导致可用的空闲内存改变,而calloc会改变?

malloc() does not use memory. malloc() 使用内存。 It allocates it. 它分配它。

After you allocate the memory, use it by assigning some data. 分配内存后,通过分配一些数据来使用它。

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

Some platforms implement malloc() is such a way that the physical consumption of memory does not occur until that byte (or more likely a byte within a group or "page" of bytes) is accessed. 某些平台实现malloc()的方式是,在访问该字节(或更可能是字节组或字节的“页”中的某个字节)之前,不会发生内存的物理消耗。

calloc() may or may not truly use the memory either. calloc()可能会也可能不会真正使用内存。 A system could map lots of memory to the same physical zeroed memory, at least until the data gets interesting. 系统可以大量内存映射到相同的物理归零内存,至少直到数据变得有趣为止。 See Why malloc+memset is slower than calloc? 请参见为什么malloc + memset比calloc慢?

The memory may not be really available, especially that you didn't do anything using p in your example except check for if it's NULL . 内存可能没有真正可用,尤其是在示例中您没有使用p做任何事情,只是检查它是否为NULL From man malloc 来自man malloc

By default, Linux follows an optimistic memory allocation strategy. 默认情况下,Linux遵循乐观的内存分配策略。 This means that when malloc() returns non- NULL there is no guarantee that the memory really is available. 这意味着,当malloc()返回非NULL ,不能保证内存确实可用。 In case it turns out that the system is out of memory, one or more processes will be killed by the OOM killer. 万一发现系统内存不足,OOM杀手将杀死一个或多个进程。 For more information, see the description of /proc/sys/vm/overcommit_memory and /proc/sys/vm/oom_adj in proc(5) , and the Linux kernel source file Documentation /vm/overcommit-accounting . 有关详细信息,请参阅的描述/proc/sys/vm/overcommit_memory/proc/sys/vm/oom_adjproc(5)和Linux内核源文件文档/vm/overcommit-accounting

The calloc on your system† actually touches the memory by clearing it, and on many systems memory is not really allocated (and thus “used up”) until it is touched by the process to which it is allocated. 您的系统†上的calloc实际上是通过清除内存来触摸内存的,在许多系统上,直到分配进程触摸到该内存后,才真正分配(因此“用完”)内存。 So just doing malloc does not “use” the memory until you, well, use it. 因此,仅当您使用好malloc它才“使用”内存。

† See comments † 看评论

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM