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

为什么malloc不';在达到某个阈值之前,我不会分配内存吗?,c,linux,malloc,dynamic-memory-allocation,C,Linux,Malloc,Dynamic Memory Allocation,我想标记的行是malloc分配的内存(可能我错了)。 但当我使用一些小数字,如10240,我看不到分配了什么: 3901: ./alloc_program 1024000 0000560192f43000 4K r---- alloc_program 0000560192f44000 4K r-x-- alloc_program 0000560192f45000 4K r---- alloc_program 0000560192f46000 4K r-

我想标记的行是malloc分配的内存(可能我错了)。 但当我使用一些小数字,如
10240
,我看不到分配了什么:

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
1-当内存大小相对较小时,为什么不进行分配


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

您在
pmap
输出中看到的几乎可以肯定是添加到
malloc
竞技场以满足更大的请求,而不是任何单个请求

竞技场是一个内存池,分配是从内存池中分配的,很有可能从某个特定的大小开始,并且只在需要时才扩展

例如,如果初始竞技场为1000K,则任何不耗尽的分配都不需要获得额外的竞技场空间。如果您确实耗尽了空间,流程将尝试从底层环境请求更多的竞技场,以便满足额外的需求


至于为什么尺寸不是你所要求的,有(至少)两个可能的原因。首先,竞技场不仅仅是为您的目的分配的内存,它还保存控制信息,以便可以正确管理内存(大小、校验和、指针、空闲列表等)

其次,
malloc
可能会过度分配,因为这不会是耗尽当前竞技场的最后一个请求。一些内存分配策略甚至在请求更多内存时将当前竞技场的大小增加一倍,以分摊这样做的成本

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

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

  • 内核一次只提供大量内存,至少一个内存,这取决于操作系统的配置,通常至少是4096字节。因此,如果应用程序只需要10字节的内存,就会浪费大量内存
  • 在CPU性能方面非常昂贵
  • 由于这些原因,
    malloc
    不直接将内存分配请求转发到内核,而是充当应用程序内存分配请求和内核之间的中介,效率更高。它从内核请求大量内存,因此可以满足来自应用程序的许多较小的内存分配请求

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


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


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

    谢谢您的回答。您所说的是否意味着分配的区域将始终是页面大小的倍数(在本例中为4096)?@StackExchange123:是的,所有内核内存分配的粒度都是一个内存页面。因此,如果是内存页大小,则所有内核内存分配都是4096的倍数。@StackExchange123:如果您使用的是GNU C库,然后,您可以使用该函数并读取
    hblkhd
    struct成员以获取内核内存分配的总大小。@StackExchange123:如果您想知道初始竞技场在哪里,那么我建议您运行
    printf(“%p”,malloc(8))
    并将显示的地址与
    pmap
    @StackExchange123显示的地图进行比较:如果您想了解有关GNU C库的内存分配器的更多信息,我建议您阅读。该页面还包含一个链接,可获取有关分配器内部的更多信息。感谢您的回答。有没有办法知道竞技场的初始规模?另外,初始竞技场在
    pmap
    的输出中显示在哪里?
    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
    
    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