C 代码:
// program break mechanism
// TLPI exercise 7-1
#include <stdio.h>
#include <stdlib.h>
void program_break_test() {
printf("%10p\n", sbrk(0));
char *bl = malloc(1024 * 1024);
printf("%x\n", sbrk(0));
free(bl);
printf("%x\n", sbrk(0));
}
int main(int argc, char **argv) {
program_break_test();
return 0;
}
编译以下代码时:
printf("%10p\n", sbrk(0));
我收到警告提示:
格式“%p”需要类型为“void *”的参数,但参数 2 的类型为“int”
问题 1:这是为什么?
在我 malloc(1024 * 1024)
之后,似乎程序中断没有改变。
这是输出:
9b12000
9b12000
9b12000
问题2:进程是否在启动时在堆上分配内存以备将来使用?还是编译器改变了分配的时间点?否则,为什么?
[更新] 总结:brk() 或 mmap()
在查看了 TLPI 并查看手册页(在 TLPI 作者的帮助下)之后,现在我明白了 malloc()
是如何决定使用 brk()
或 mmap()
,如下:
mallopt()
可以通过设置参数来控制malloc()
的行为,其中有一个名为M_MMAP_THRESHOLD
的参数,一般来说:
- 如果请求的内存小于它,将使用
brk()
; - 如果请求的内存大于或等于它,将使用
mmap()
;
参数的默认值是128kb
(在我的系统上),但在我的测试程序中我使用了1Mb,所以选择了mmap()
,当我改变请求内存到 32kb,我看到 brk()
会被使用。
这本书在TLPI 147和1035页提到了,但我没有仔细阅读那部分。
参数的详细信息可以在 mallopt()
的手册页中找到。
最佳答案
如果我们更改程序以查看 malloc
的内存位置:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void program_break_test() {
printf("%10p\n", sbrk(0));
char *bl = malloc(1024 * 1024);
printf("%10p\n", sbrk(0));
printf("malloc'd at: %10p\n", bl);
free(bl);
printf("%10p\n", sbrk(0));
}
int main(int argc, char **argv) {
program_break_test();
return 0;
}
sbrk
不会改变可能更清楚一点。 malloc
提供给我们的内存被映射到一个截然不同的位置。
您还可以在 Linux 上使用 strace
查看进行了哪些系统调用,并找出 malloc
正在使用 mmap
执行分配。
关于c - malloc() 使用 brk() 还是 mmap()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30542428/