c - malloc() 使用 brk() 还是 mmap()?

标签 c memory-management malloc mmap sbrk

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/

相关文章:

c++ - 无法将控制台输出写入 C 或 C++ 文件

c++ - 为什么这不会给出重新声明错误?

颜色转换在 opencv 中不起作用?

C++ 内存分配 howto

c - 理解 C 语言中的 StrBuff

c++ - 如何获取使用 malloc() 分配的内存块的大小?

c - 需要帮助解决不可分页内存的内存问题

c - 使用 C 将 u64 的数组重新解释为 u16 的 3D,而无需更改内存分配

C: Malloc 和 Free

c++ - 如何跨 DLL 边界跟踪内存