malloc
使用brk
/sbrk
作为从操作系统申请内存的主要方式的典型实现。但是,它们也用于mmap
获取大分配的块。使用brk
而不是有真正的好处mmap
,还是只是传统?用它来做这一切难道不一样mmap
吗?
(注意:我在这里使用sbrk
和brk
互换,因为它们是同一个 Linux 系统调用的接口,brk
。)
作为参考,这里有一些描述 glibc 的文档malloc
:
GNU C 库参考手册:GNU 分配器
https://www.gnu.org/software/libc/manual/html_node/The-GNU-Allocator.html
glibc wiki:Malloc 概述
https://sourceware.org/glibc/wiki/MallocInternals
这些文档描述的sbrk
是用于为小分配声明主要区域,mmap
用于声明次要区域,mmap
也用于为大对象声明空间(“比页面大得多”)。
使用应用程序堆(用 声明sbrk
)并mmap
引入了一些可能不必要的额外复杂性:
分配的竞技场 - 主竞技场使用应用程序的堆。其他竞技场使用
mmap
'd heaps。要将块映射到堆,您需要知道适用哪种情况。如果该位为 0,则该块来自主竞技场和主堆。如果该位为 1,则块来自mmap
'd 内存,并且堆的位置可以从块的地址计算。
【glibc mallocptmalloc
派生自dlmalloc, dlmalloc 始于 1987 年。】
jemalloc手册页(http://jemalloc.net/jemalloc.3.html)有这样的说法:
传统上,分配器用于
sbrk(2)
获取内存,这是次优的,原因有几个,包括竞争条件、增加的碎片和对最大可用内存的人为限制。如果sbrk(2)
操作系统支持,则此分配器mmap(2)
按优先顺序同时使用和 sbrk(2);否则仅mmap(2)
使用。
因此,他们甚至在这里说这sbrk
是次优的,但他们仍然使用它,即使他们已经费心编写代码以便没有它也能正常工作。
[jemalloc 的编写始于 2005 年。]
更新:再想一想,关于“按优先顺序”的那一点给了我一条询问线。为什么是优先顺序?它们是否只是在不支持(或缺少必要的功能)sbrk
的情况下用作后备mmap
,或者该过程是否有可能进入某种可以使用sbrk
但不能使用的状态mmap
?我会看看他们的代码,看看我是否能弄清楚它在做什么。
我问是因为我正在用 C 实现一个垃圾收集系统,到目前为止,我认为没有理由使用除mmap
. 不过,我想知道我是否缺少某些东西。
(在我的情况下,我还有一个额外的理由要避免brk
,那就是我可能需要malloc
在某些时候使用。)