Trầ*_* Hà 5 c linux malloc memory-management
我正在研究内存管理,并且有一个关于 malloc 如何工作的问题。malloc手册页指出:
通常,
malloc()从堆中分配内存,并根据需要调整堆的大小,使用sbrk(2). 当分配大于MMAP_THRESHOLD字节的内存块时,glibcmalloc()实现会使用mmap(2).MMAP_THRESHOLD默认情况下为 128 kB,但可以使用 进行调整mallopt(3)。
为了验证一下,我用一段代码做了实验:
#include<stdlib.h>
#include<stdio.h>
int main()
{
int size = 10;
int *p = malloc(size);
if(p)
{
printf("allocated %d bytes at addr: %p \n", size, p);
free(p);
}
else
{
free(p);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我用strace跟踪了这个程序,看看使用了什么系统调用。结果如下:
为什么在这个例子中malloc调用mmap而不是brk?
mmap()当程序加载共享库时,所有这些调用都是程序启动的一部分。这是您在strace大多数程序中都会看到的标准内容。
真正的动作在最后几行:
brk()打来的两个电话malloc()。fstat()电话write()从 打来printf()。您可以在顶部添加打印输出,main()以查看代码何时实际开始运行。
(直接调用write()系统调用而不是使用printf()or打印非常重要puts()。stdio 函数malloc()在内部调用,这会混淆我们要测试的内容。)
#include <unistd.h>
int main()
{
write(1, "start\n", 6);
...
}
Run Code Online (Sandbox Code Playgroud)
当我这样做时,我write()在 之前看到了调用brk(NULL),我在下面用空行标记了它:
...
mmap(0x7f1b34802000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f1b34802000
mmap(0x7f1b34808000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f1b34808000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7f1b34a124c0) = 0
mprotect(0x7f1b34802000, 16384, PROT_READ) = 0
mprotect(0x558c3cd9a000, 4096, PROT_READ) = 0
mprotect(0x7f1b34a33000, 4096, PROT_READ) = 0
munmap(0x7f1b34a13000, 128122) = 0
write(1, "start\n", 6) = 6
brk(NULL) = 0x558c3dc58000
brk(0x558c3dc79000) = 0x558c3dc79000
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 4), ...}) = 0
write(1, "allocated 10 bytes at addr: 0x55"..., 44) = 44
exit_group(0) = ?
+++ exited with 0 +++
Run Code Online (Sandbox Code Playgroud)