Skip to content

Instantly share code, notes, and snippets.

@leveryd
Created November 11, 2021 07:10
Show Gist options
  • Save leveryd/d54c2b2d1b6c755fa216cd73f2e9e874 to your computer and use it in GitHub Desktop.
Save leveryd/d54c2b2d1b6c755fa216cd73f2e9e874 to your computer and use it in GitHub Desktop.

背景

#include <stdio.h>
#include <malloc.h>

int main() {
    int *m = NULL, *n = NULL;
    printf("begin\n");
    m = malloc(64 * 1024);
    getchar();
    n = malloc(256 * 1024);
    getchar();
    printf("end\n");
    free(m);
    free(n);
    return 0;
}

运行时的系统调用

[root@vm10-50-0-18 tmp]# strace ./a.out
...
write(1, "begin\n", 6begin
)                  = 6
brk(NULL)                               = 0xd80000
brk(0xdb1000)                           = 0xdb1000
brk(NULL)                               = 0xdb1000
fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7f7de96000
read(0,
"\n", 1024)                     = 1
mmap(NULL, 266240, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7f7de46000

疑问:

  • 为什么在mmap前有三个brk操作?
  • 为什么第一个mmap大小是4096?
  • 案例中的malloc申请内存,到底是用brk还是mmap?

分析

  • 对比分析

    注释 m = malloc(64 * 1024);,发现仍然有 fstat、mmap 系统调用

    fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7f7de96000
    

    image

    可以得出结论:

    • 系统调用中的 fstat、mmap 这两行和 m = malloc(64 * 1024); 无关,应该是getchar()导致的

总结

  • 此案例可以验证结论:malloc申请小内存时使用brk,申请大内存时使用mmap
  • 系统调用中的 fstat、mmap 这两行和 m = malloc(64 * 1024); 无关

疑问

  • brk(NULL) 是什么意思?

    获得当前堆 的地址

  • "小内存"和"大内存"的界限是什么?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment