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

时间:2017-05-24 06:28:48

标签: c memory-management operating-system malloc

使用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 fail\n");                                                     
  }
  //else                                                                        
  //{                                                                           
     //printf("memory allocated at %p\n", 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调用是否可以延迟内存分配,直到它被引用?

我正在使用的配置

  1. Linux nightfury 4.4.0-78-generic#99-Ubuntu SMP Thu 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

1 个答案:

答案 0 :(得分:3)

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

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