我想知道如果堆上所需的空间不够大 这样就不需要一个brk / sbrk系统(移动数据段的中断指针(brk)),库函数(如malloc)如何在堆上分配空间。 我不是在询问堆管理的数据结构和算法。我只是问如果malloc没有调用系统调用,它如何获取堆的第一个位置的地址。我问这个是因为我听说并不总是需要调用系统调用(brk / sbrk),因为只需要扩展空间。如果我错了,请纠正我。
答案 0 :(得分:3)
基本思想是,当你的程序启动时,堆非常小,但不一定是零。如果只分配(malloc)少量内存,则库可以在加载时占用少量空间。但是,当malloc耗尽该空间时,需要进行系统调用以获得更多内存。
该系统调用通常是sbrk(),它将堆的内存区域的顶部向上移动一定量。通常,malloc库例程比当前分配所需的更大增加堆,希望未来的分配可以在不进行系统调用的情况下执行。
malloc的其他实现使用mmap()代替 - 这允许程序创建稀疏虚拟内存映射。但是,基于mmap()的malloc实现与基于sbrk()的实现完全相同:每个系统调用都会保留比当前调用所需内存更多的内存。
查看此问题的一种方法是跟踪使用malloc的程序:您将看到对于对malloc的N次调用,您将看到M系统调用(其中M远小于N)。
答案 1 :(得分:2)
简短的回答是它使用sbrk()来分配一个大块,在那时它属于你的app进程。然后,它可以进一步分割出单个malloc调用的子部分,而无需向系统询问任何内容,直到它耗尽该空间并需要再次使用sbrk()。
你说过你不想要数据结构的细节,但足以说malloc的实现(即你自己的进程,而不是操作系统内核)正在跟踪它所来自的区域中的哪个空间该系统是专用的,并且仍然可以作为单独的mallocs发布。这就像购买大片土地,然后将其细分为个别房屋。
答案 2 :(得分:-1)
使用sbrk()或mmap() - http://linux.die.net/man/2/sbrk,http://linux.die.net/man/2/mmap