C++ Malloc 不调用 mmap 或 brk?

问题描述

在 ubuntu 18.04 上,我编写了以下 c 程序并以 100 的输入运行它

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

int main() {
    int x;
    scanf("%d",&x);
    usleep(1);
    void *tmp = malloc(x);
    usleep(1);
    free(tmp);
    return 0;
}

终端的输出是:(带strace)

strace ./a.out
execve("./a.out",["./a.out"],0x7ffd69236c10 /* 50 vars */) = 0
brk(NULL)                               = 0x55a719717000
access("/etc/ld.so.nohwcap",F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload",R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD,"/etc/ld.so.cache",O_RDONLY|O_CLOEXEC) = 3
fstat(3,{st_mode=S_IFREG|0644,st_size=96020,...}) = 0
mmap(NULL,96020,PROT_READ,MAP_PRIVATE,3,0) = 0x7f7acb879000
close(3)                                = 0
access("/etc/ld.so.nohwcap",F_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD,"/lib/x86_64-linux-gnu/libc.so.6",O_RDONLY|O_CLOEXEC) = 3
read(3,"\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\35\2\0\0\0\0\0"...,832) = 832
fstat(3,{st_mode=S_IFREG|0755,st_size=2030928,8192,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0x7f7acb877000
mmap(NULL,4131552,PROT_READ|PROT_EXEC,MAP_PRIVATE|MAP_DENYWRITE,0) = 0x7f7acb277000
mprotect(0x7f7acb45e000,2097152,PROT_NONE) = 0
mmap(0x7f7acb65e000,24576,MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE,0x1e7000) = 0x7f7acb65e000
mmap(0x7f7acb664000,15072,MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,0) = 0x7f7acb664000
close(3)                                = 0
arch_prctl(ARCH_SET_FS,0x7f7acb8784c0) = 0
mprotect(0x7f7acb65e000,16384,PROT_READ) = 0
mprotect(0x55a718d34000,4096,PROT_READ) = 0
mprotect(0x7f7acb891000,PROT_READ) = 0
munmap(0x7f7acb879000,96020)           = 0
fstat(0,{st_mode=S_IFCHR|0620,st_rdev=makedev(136,0),...}) = 0
brk(NULL)                               = 0x55a719717000
brk(0x55a719738000)                     = 0x55a719738000
read(0,100
"100\n",1024)                  = 4
nanosleep({tv_sec=0,tv_nsec=1000},NULL) = 0
nanosleep({tv_sec=0,NULL) = 0
lseek(0,SEEK_CUR)                  = -1 ESPIPE (Illegal seek)
exit_group(0)                           = ?
+++ exited with 0 +++

这不是很奇怪吗?为什么 malloc 没有使用 brkmmap 来分配内存(在 nanosleep() 的 2 次调用之间)。 这种奇怪行为的原因是什么?

如果我将输入更改为 200000,我会在两者之间看到对 mmap 的调用

解决方法

这不奇怪吗?

没有

为什么 malloc 不使用 brk 或 mmap 来分配内存(在两次调用 nanosleep() 之间)。

场景 1:您启用了优化,并且优化器发现忽略对 malloc 的调用是不可观察的,因此它从未被调用过。

场景 2:调用了 malloc,但在那时它大概不需要调用 brkmmapbrkmmap 之前都被调用过,可能是为了 malloc