我正在读一些关于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
获取的页面可以通过munmap
发布,这是glibc正在做的事情。 因此,对于小的分配, free
将内存free
到进程的堆(但将它们保留在进程的内存中); 对于大的分配,整个系统可以free
返回内存。
(2)通过匿名mmap
获取的页面在第一次访问之前并不实际分配。 此时,内核必须将其清零,以避免进程之间泄漏信息。 所以,是的,通过mmap
获得的页面比通过你的进程堆回收的页面第一次访问要慢。 您是否会注意到差异取决于您的应用程序。
不使用mmap
的成本是,释放的内存仍然受到进程的束缚,并且不可用于系统上的其他进程。 所以这最终是一个折衷。
(3)它不“强制”上下文切换,而且我相信这不太可能导致上下文切换。 mmap
实际上并没有分配页面; 它只是操纵你的过程的页面地图。 这通常应该是一个非阻塞操作。 (虽然我承认我不是100%确定的)。