我对mmap()
系统调用感到有点困惑。我意识到它映射了内存,我不明白的是从应用程序调用mmap()
调用如何干扰(或不)已经运行的malloced细分,特别是使用sbrk()
分配的细分。
让我解释一下我所得到的更多内容:假设我通过简单的malloc(x);
x < 1MB
分配了几个结构。根据glibc,这些调用将使用sbrk()调用(v2.15 / malloc.c)来满足,这将使数据段向上增长。
sbrk()
会导致虚拟数据段连续增长。所以我的问题是,当sbrk()
被调用到通过mmap()
分配的内存区域时会发生什么。
对此有何想法或评论? 非常感激!
答案 0 :(得分:2)
我在64位OS X(Mountain Lion)上尝试了一些实验。 sbrk
和mmap
文档并未相互引用,因此其中一些是在行间读取,但它看起来像:
sbrk
成长的大片区域。超过该预订时,sbrk
将失败。mmap
选择地图的位置(在没有MAP_FIXED
标记的情况下调用),则会选择sbrk
预订以外的区域。sbrk
和mmap
不会相互干扰。此外,无论实现malloc
使用哪种实现,它都应该接受它获得的内存并将其合并到数据库中而不会出现问题,无论是从sbrk
还是从mmap
获取内存还是从其他地方获取内存。并且它不应干扰程序对sbrk
和mmap
的独立正常使用。mmap
致电MAP_FIXED
并指定保留区域sbrk
中的地址,那么mmap
将在那里映射内存。sbrk
之后再次呼叫mmap
,则sbrk
将返回成功,即使新的中断地址与使用mmap
映射的内存重叠。此时,您的程序可能已损坏。因此,将mmap
与MAP_FIXED
一起使用是不明智的,除非您有充分的理由知道您指定的地址是可以的。
答案 1 :(得分:1)
堆和堆栈之间的简单划分是一种简化。现代操作系统支持大型虚拟地址空间,并且进程可以看到许多独立的内存区域。虽然这些区域是同一地址空间的一部分,但它们并不是连续的,它们中有漏洞。地址mmap()
返回的是众多漏洞之一:它可能位于堆栈之后,堆栈之后,堆之前 - 只要这些区域永远不会满足,它就不会产生影响。 / p>
还要记住,在一个线程程序中没有单个堆栈,其中有多个与线程一样多。