为什么 malloc 在我达到某个阈值之前不分配内存?

Sta*_*123 2 c linux malloc dynamic-memory-allocation

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

int main(int argc, char *argv[])
{
        size_t sz = atol(argv[1]);
        char *arr = malloc(sz);

        sleep(10);
}
Run Code Online (Sandbox Code Playgroud)

我编译了这段代码并尝试运行它,用于pmap查看程序的内存映射。

当我使用一些大数字时1024000,我会得到这样的映射:

3901:   ./alloc_program 1024000
0000560192f43000      4K r---- alloc_program
0000560192f44000      4K r-x-- alloc_program
0000560192f45000      4K r---- alloc_program
0000560192f46000      4K r---- alloc_program
0000560192f47000      4K rw--- alloc_program
0000560192fac000    132K rw---   [ anon ]
00007f75b69e9000   1004K rw---   [ anon ]     <---- I believe this is the allocated memory
00007f75b6ae4000    148K r---- libc-2.31.so
00007f75b6b09000   1504K r-x-- libc-2.31.so
00007f75b6c81000    296K r---- libc-2.31.so
00007f75b6ccb000      4K ----- libc-2.31.so
00007f75b6ccc000     12K r---- libc-2.31.so
00007f75b6ccf000     12K rw--- libc-2.31.so
00007f75b6cd2000     24K rw---   [ anon ]
00007f75b6ce7000      4K r---- ld-2.31.so
00007f75b6ce8000    140K r-x-- ld-2.31.so
00007f75b6d0b000     32K r---- ld-2.31.so
00007f75b6d14000      4K r---- ld-2.31.so
00007f75b6d15000      4K rw--- ld-2.31.so
00007f75b6d16000      4K rw---   [ anon ]
00007ffe2b26e000    132K rw---   [ stack ]
00007ffe2b318000     12K r----   [ anon ]
00007ffe2b31b000      4K r-x--   [ anon ]
ffffffffff600000      4K --x--   [ anon ]
 total             3496K
Run Code Online (Sandbox Code Playgroud)

我想标记的行是 malloc 分配的内存(也许我错了)。但是当我使用一些小的数字时10240,我没有看到分配了任何东西:

3879:   ./alloc_program 10240
000055e428e26000      4K r---- alloc_program
000055e428e27000      4K r-x-- alloc_program
000055e428e28000      4K r---- alloc_program
000055e428e29000      4K r---- alloc_program
000055e428e2a000      4K rw--- alloc_program
000055e42a257000    132K rw---   [ anon ]
00007f102332c000    148K r---- libc-2.31.so
00007f1023351000   1504K r-x-- libc-2.31.so
00007f10234c9000    296K r---- libc-2.31.so
00007f1023513000      4K ----- libc-2.31.so
00007f1023514000     12K r---- libc-2.31.so
00007f1023517000     12K rw--- libc-2.31.so
00007f102351a000     24K rw---   [ anon ]
00007f102352f000      4K r---- ld-2.31.so
00007f1023530000    140K r-x-- ld-2.31.so
00007f1023553000     32K r---- ld-2.31.so
00007f102355c000      4K r---- ld-2.31.so
00007f102355d000      4K rw--- ld-2.31.so
00007f102355e000      4K rw---   [ anon ]
00007fff1d513000    132K rw---   [ stack ]
00007fff1d570000     12K r----   [ anon ]
00007fff1d573000      4K r-x--   [ anon ]
ffffffffff600000      4K --x--   [ anon ]
 total             2492K
Run Code Online (Sandbox Code Playgroud)

1 - 当内存大小相对较小时,为什么不分配?

2 - 为什么分配的内存大小不完全相同?在第一次运行时,它显示大小是1004KB我只分配了1000KB.

And*_*zel 5

1 - 当内存大小相对较小时,为什么不分配?

该函数的任务malloc是在应用程序需要内存时为其提供内存。从理论上讲,malloc正如您所建议的那样,可以将所有内存分配请求转发给操作系统的内核,以便它仅充当内核内存分配器的包装器。但是,这有以下缺点:

  1. 内核一次只提供大量内存,至少一页内存,根据操作系统的配置,通常至少为4096字节。因此,如果应用程序仅要求 10 字节的内存,则会浪费大量内存。
  2. 就 CPU 性能而言,系统调用是昂贵的。

由于这些原因,malloc不将内存分配请求直接转发到内核,而是充当应用程序的内存分配请求和内核之间的中介,效率更高。它从内核请求大量的内存,这样它就可以满足来自应用程序的许多较小的内存分配请求。

因此,只有在一次请求大量内存时,才会malloc将该内存分配请求转发给内核。


2 - 为什么分配的内存大小不完全相同?在第一次运行时,它显示大小是1004KB我只分配了1000KB.

malloc分配器必须跟踪所有它授予应用程序的内存分配,并跟踪所有的内存分配,它已被由内核授予的。为了存储这些信息,它需要一些额外的内存空间。这个额外的空间称为“开销”。