【问题标题】:multiple malloc calls internally calling mmap only once多个 malloc 调用在内部仅调用一次 mmap
【发布时间】:2016-10-16 06:14:29
【问题描述】:

当我尝试下面的代码时,我无法清楚地分析 malloc api 内部调用。我不清楚的是系统调用 mmap 只为 2 个或多个 malloc 调用调用一次。如果我分配的内存超过 4069字节也它在内部仅调用一个 mmap(使用 strace -p processid 标识跟踪)。

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

main()
{
int *p,*q;
sleep(20);
p=malloc(5096);
printf("p=%p\n",p);
q=malloc(4096);
printf("q=%p\n",q);
sleep(2);
return 0;
}

strace 输出:

root@TEST:/home/harish# strace  -p 6109
Process 6109 attached
restart_syscall(<... resuming interrupted call ...>
) = 0
brk(0)                                  = 0xeca000
brk(0xeec000)                           = 0xeec000
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 14), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f10b7bc7000
write(1, "p=0xeca010\n", 11)            = 11
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({20, 0},
0x7ffc34a51790)      = 0
write(1, "q=0xecb020\n", 11)            = 11
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({2, 0}, 0x7ffc34a51790)       = 0
exit_group(0)                           = ?
+++ exited with 0 +++

我正在寻找的是,如果 malloc 使用得更多,那么它会调用一个以上的 mmap,因为内存超过了两个 malloc 超过 4096

【问题讨论】:

  • 这就是malloc 的实现方式。你应该研究malloc的源代码,以了解它是如何实现的。
  • 在哪里可以看到malloc的主要代码。请提供路径
  • 我刚刚搜索了“malloc 源代码”,看到了多个不错的结果。你尝试了什么?
  • 我试图检查 glibc 源代码

标签: c memory malloc sbrk brk


【解决方案1】:

您的进程的内部堆(通过 malloc、free 和 realloc 访问)管理它认为合适的内存 - 这包括:

  • 以大的或固定的增量增长堆,以分摊昂贵的 brk/sbrk 系统调用在多次(取消)分配上的成本
  • 在该堆区域本身内处理较小的(取消)分配
  • 管理分配记录的(去)碎片化

对于大小分配使用不同的机制也很常见,例如从brk/sbrk 管理的连续区域分配小对象,但可以使用mmap 直接分配单个大对象。

【讨论】:

  • 但是在我的代码中注释 printf 后,我看不到跟踪中的任何 mmap,只有 brk 显示两次。所以我期待的是 mmap 与 malloc 没有任何关系
  • 我说 malloc 可以在某些实现中对某些分配使用mmap。这不是强制性的。如果您想了解 您的 实现中发生了什么,请阅读代码。
【解决方案2】:

malloc() 不会导致mmap() 调用。通常它会导致brk()。但是,并非每次调用都会导致brk()。这在很大程度上取决于当前分配的页面、请求的内存和其他因素。

【讨论】:

  • 但是内存分配方式是通过 mmap 进行的,如果我错了,请纠正我。
  • @harish,那个mmap' might be due to other code like printf()`。
  • 这可能是一个愚蠢的问题,但请给我一些理解的指导,比如什么时候会调用 brk 以及什么时候会在 malloc 内部调用 sbrk 不清楚
  • 这是 malloc 故意不公开的实现细节,因此您不必担心。如果你担心它,你需要阅读实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-06
  • 1970-01-01
相关资源
最近更新 更多