为什么malloc依赖于从某个阈值开始的mmap?

我正在读一些关于malloc的信息,并在malloc的手册页中find了以下内容:

通常,malloc()从堆中分配内存,并根据需要使用sbrk(2)调整堆的大小。 当分配大于MMAP_THRESHOLD字节的内存块时,glibc malloc()实现使用mmap(2)将内存分配为专用匿名映射。 MMAP_THRESHOLD默认为128 kB,但可以使用mallopt(3)进行调整。 使用mmap(2)执行的分配不受RLIMIT_DATA资源限制的影响(请参阅getrlimit(2))。

所以基本上从阈值MMAP_THRESHOLD malloc开始使用mmap开始。

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

(1)通过匿名mmap获取的页面可以通过munmap发布,这是glibc正在做的事情。 因此,对于小的分配, free将内存free到进程的堆(但将它们保留在进程的内存中); 对于大的分配,整个系统可以free返回内存。

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

不使用mmap的成本是,释放的内存仍然受到进程的束缚,并且不可用于系统上的其他进程。 所以这最终是一个折衷。

(3)它不“强制”上下文切换,而且我相信这不太可能导致上下文切换。 mmap实际上并没有分配页面; 它只是操纵你的过程的页面地图。 这通常应该是一个非阻塞操作。 (虽然我承认我不是100%确定的)。