使用 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 调用是否可以延迟内存分配,直到它被引用?
我正在使用的配置
Linuxnightfury 4.4.0-78-generic #99-Ubuntu SMP 星期四 Apr 27 15:29:09 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
C 标准没有说明堆,因此,malloc()
的实现可以自由地以任何合适的方式分配内存。例如,这可能来自不提供内存管理的平台上数据段中的固定大型缓冲区。
在glibc
的情况下,如果请求的块足够大,malloc
默认使用mmap
分配内存。传统堆(通过sbrk
)仅用于较小的分配。