为什么malloc依赖mmap从某个阈值开始?
Why does malloc rely on mmap starting from a certain threshold?
我阅读了一些关于 malloc
的内容,并在 malloc
的手册页中找到了以下内容:
Normally, malloc() allocates memory from the heap, and adjusts the
size of the heap as required, using sbrk(2). When allocating blocks
of memory larger than MMAP_THRESHOLD bytes, the glibc malloc()
implementation allocates the memory as a private anonymous mapping
using mmap(2). MMAP_THRESHOLD is 128 kB by default, but is
adjustable using mallopt(3). Allocations performed using mmap(2) are
unaffected by the RLIMIT_DATA resource limit (see getrlimit(2)).
所以基本上是从阈值MMAP_THRESHOLD malloc开始使用mmap
.
- 是否有任何理由为大块切换到
mmap
?
- 这会影响流程执行性能吗?
mmap
系统调用是否强制上下文切换?
(1) 通过匿名mmap
获得的页面可以通过munmap
释放,这就是glibc所做的。因此,对于小分配,free
returns 内存到进程的堆(但将它们保留在进程的内存中);对于大型分配,free
returns 整个系统的内存。
(2) 通过匿名 mmap
获取的页面在您第一次访问它们之前不会实际分配。那时,内核必须将它们归零以避免在进程之间泄漏信息。所以,是的,由 mmap
获取的页面在第一次访问时比通过进程堆回收的页面慢。您是否会注意到差异取决于您的应用程序。
不使用 mmap
的代价是释放的内存仍然被您的进程占用,系统上的其他进程无法使用。所以这最终是一个权衡。
(3) 它不会 "force" 上下文切换,而且我认为不太可能导致上下文切换。 mmap
实际上没有分配页面;它只是为您的流程操纵页面映射。这通常应该是一个非阻塞操作。 (虽然我承认我对此不是 100% 确定。)
我阅读了一些关于 malloc
的内容,并在 malloc
的手册页中找到了以下内容:
Normally, malloc() allocates memory from the heap, and adjusts the size of the heap as required, using sbrk(2). When allocating blocks of memory larger than MMAP_THRESHOLD bytes, the glibc malloc() implementation allocates the memory as a private anonymous mapping using mmap(2). MMAP_THRESHOLD is 128 kB by default, but is adjustable using mallopt(3). Allocations performed using mmap(2) are unaffected by the RLIMIT_DATA resource limit (see getrlimit(2)).
所以基本上是从阈值MMAP_THRESHOLD malloc开始使用mmap
.
- 是否有任何理由为大块切换到
mmap
? - 这会影响流程执行性能吗?
mmap
系统调用是否强制上下文切换?
(1) 通过匿名mmap
获得的页面可以通过munmap
释放,这就是glibc所做的。因此,对于小分配,free
returns 内存到进程的堆(但将它们保留在进程的内存中);对于大型分配,free
returns 整个系统的内存。
(2) 通过匿名 mmap
获取的页面在您第一次访问它们之前不会实际分配。那时,内核必须将它们归零以避免在进程之间泄漏信息。所以,是的,由 mmap
获取的页面在第一次访问时比通过进程堆回收的页面慢。您是否会注意到差异取决于您的应用程序。
不使用 mmap
的代价是释放的内存仍然被您的进程占用,系统上的其他进程无法使用。所以这最终是一个权衡。
(3) 它不会 "force" 上下文切换,而且我认为不太可能导致上下文切换。 mmap
实际上没有分配页面;它只是为您的流程操纵页面映射。这通常应该是一个非阻塞操作。 (虽然我承认我对此不是 100% 确定。)