为什么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.

  1. 是否有任何理由为大块切换到 mmap
  2. 这会影响流程执行性能吗?
  3. mmap系统调用是否强制上下文切换?

(1) 通过匿名mmap获得的页面可以通过munmap释放,这就是glibc所做的。因此,对于小分配,free returns 内存到进程的堆(但将它们保留在进程的内存中);对于大型分配,free returns 整个系统的内存。

(2) 通过匿名 mmap 获取的页面在您第一次访问它们之前不会实际分配。那时,内核必须将它们归零以避免在进程之间泄漏信息。所以,是的,由 mmap 获取的页面在第一次访问时比通过进程堆回收的页面慢。您是否会注意到差异取决于您的应用程序。

不使用 mmap 的代价是释放的内存仍然被您的进程占用,系统上的其他进程无法使用。所以这最终是一个权衡。

(3) 它不会 "force" 上下文切换,而且我认为不太可能导致上下文切换。 mmap 实际上没有分配页面;它只是为您的流程操纵页面映射。这通常应该是一个非阻塞操作。 (虽然我承认我对此不是 100% 确定。)