c - 为什么在内存分配较大的情况下不显示堆区域?



使用 malloc 分配大内存区域后,我正在尝试检查/proc/[pid]/maps文件中堆区域的跨度。下面是我写的代码。

#include <stdio.h>                                                              
#include <stdlib.h>                                                             
#include <unistd.h>                                                             
int main()                                                                      
{                                                                               
void *p = malloc(1024LL * 1024LL * 1024LL * 4);                                                    
if (p == NULL)                                                                
{                                                                             
printf("alloc failn");                                                     
}
//else                                                                        
//{                                                                           
//printf("memory allocated at %pn", p);                                    
//}                                                                             
while (1) sleep(1);                                                           
free(p);                                                                      
return 0;                                                                     
}    

当我检查/proc/[pid]/maps文件时,没有显示堆区域的映射。

00400000-00401000 r-xp 00000000 08:01 20185722                           /home/soumen/a.out
00600000-00601000 r--p 00000000 08:01 20185722                           /home/soumen/a.out
00601000-00602000 rw-p 00001000 08:01 20185722                           /home/soumen/a.out
7f19f98df000-7f1af98e0000 rw-p 00000000 00:00 0 
7f1af98e0000-7f1af9a9f000 r-xp 00000000 08:01 23462292                   /lib/x86_64-linux-gnu/libc-2.23.so
7f1af9a9f000-7f1af9c9f000 ---p 001bf000 08:01 23462292                   /lib/x86_64-linux-gnu/libc-2.23.so
7f1af9c9f000-7f1af9ca3000 r--p 001bf000 08:01 23462292                   /lib/x86_64-linux-gnu/libc-2.23.so
7f1af9ca3000-7f1af9ca5000 rw-p 001c3000 08:01 23462292                   /lib/x86_64-linux-gnu/libc-2.23.so
7f1af9ca5000-7f1af9ca9000 rw-p 00000000 00:00 0 
7f1af9ca9000-7f1af9ccf000 r-xp 00000000 08:01 23462295                   /lib/x86_64-linux-gnu/ld-2.23.so
7f1af9ea4000-7f1af9ea7000 rw-p 00000000 00:00 0 
7f1af9ecc000-7f1af9ece000 rw-p 00000000 00:00 0 
7f1af9ece000-7f1af9ecf000 r--p 00025000 08:01 23462295                   /lib/x86_64-linux-gnu/ld-2.23.so
7f1af9ecf000-7f1af9ed0000 rw-p 00026000 08:01 23462295                   /lib/x86_64-linux-gnu/ld-2.23.so
7f1af9ed0000-7f1af9ed1000 rw-p 00000000 00:00 0 
7ffe71fe1000-7ffe72002000 rw-p 00000000 00:00 0                          [stack]
7ffe72094000-7ffe72096000 r--p 00000000 00:00 0                          [vvar]
7ffe72096000-7ffe72098000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

现在我取消注释代码中的 else 部分并再次运行它。这一次,堆区域出现在/proc/[pid]/maps文件中。但它比正在分配的要小得多。

此外,分配区域的起始地址不在/proc/[pid]/maps文件中显示的堆区域限制内。

程序输出:

memory allocated at 0x7fcab87e2010

/proc/[pid]/maps文件的内容

00400000-00401000 r-xp 00000000 08:01 20185722                           /home/soumen/a.out
00600000-00601000 r--p 00000000 08:01 20185722                           /home/soumen/a.out
00601000-00602000 rw-p 00001000 08:01 20185722                           /home/soumen/a.out
00bba000-00bdb000 rw-p 00000000 00:00 0                                  [heap]
7fcab87e2000-7fcbb87e3000 rw-p 00000000 00:00 0 
7fcbb87e3000-7fcbb89a2000 r-xp 00000000 08:01 23462292                   /lib/x86_64-linux-gnu/libc-2.23.so
7fcbb89a2000-7fcbb8ba2000 ---p 001bf000 08:01 23462292                   /lib/x86_64-linux-gnu/libc-2.23.so
7fcbb8ba2000-7fcbb8ba6000 r--p 001bf000 08:01 23462292                   /lib/x86_64-linux-gnu/libc-2.23.so
7fcbb8ba6000-7fcbb8ba8000 rw-p 001c3000 08:01 23462292                   /lib/x86_64-linux-gnu/libc-2.23.so
7fcbb8ba8000-7fcbb8bac000 rw-p 00000000 00:00 0 
7fcbb8bac000-7fcbb8bd2000 r-xp 00000000 08:01 23462295                   /lib/x86_64-linux-gnu/ld-2.23.so
7fcbb8da7000-7fcbb8daa000 rw-p 00000000 00:00 0 
7fcbb8dcf000-7fcbb8dd1000 rw-p 00000000 00:00 0 
7fcbb8dd1000-7fcbb8dd2000 r--p 00025000 08:01 23462295                   /lib/x86_64-linux-gnu/ld-2.23.so
7fcbb8dd2000-7fcbb8dd3000 rw-p 00026000 08:01 23462295                   /lib/x86_64-linux-gnu/ld-2.23.so
7fcbb8dd3000-7fcbb8dd4000 rw-p 00000000 00:00 0 
7fff2df8f000-7fff2dfb0000 rw-p 00000000 00:00 0                          [stack]
7fff2dfec000-7fff2dfee000 r--p 00000000 00:00 0                          [vvar]
7fff2dfee000-7fff2dff0000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

那么操作系统在这里做了什么?malloc 调用是否可以延迟内存分配,直到它被引用?

我正在使用的配置

Linux
  1. nightfury 4.4.0-78-generic #99-Ubuntu SMP 星期四 Apr 27 15:29:09 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

  2. gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609

C 标准没有说明堆,因此,malloc()的实现可以自由地以任何合适的方式分配内存。例如,这可能来自不提供内存管理的平台上数据段中的固定大型缓冲区。

glibc的情况下,如果请求的块足够大,malloc默认使用mmap分配内存。传统堆(通过sbrk)仅用于较小的分配。

相关内容

  • 没有找到相关文章

最新更新