mmap(),内存在虚拟空间中的位置?

时间:2013-04-26 19:34:25

标签: c unix mmap virtual-memory

我对mmap()系统调用感到有点困惑。我意识到它映射了内存,我不明白的是从应用程序调用mmap()调用如何干扰(或不)已经运行的malloced细分,特别是使用sbrk()分配的细分。

让我解释一下我所得到的更多内容:假设我通过简单的malloc(x); x < 1MB分配了几个结构。根据glibc,这些调用将使用sbrk()调用(v2.15 / malloc.c)来满足,这将使数据段向上增长。

sbrk()会导致虚拟数据段连续增长。所以我的问题是,当sbrk()被调用到通过mmap()分配的内存区域时会发生什么。

对此有何想法或评论? 非常感激!

2 个答案:

答案 0 :(得分:2)

我在64位OS X(Mountain Lion)上尝试了一些实验。 sbrkmmap文档并未相互引用,因此其中一些是在行间读取,但它看起来像:

  • 保留了sbrk成长的大片区域。超过该预订时,sbrk将失败。
  • 如果允许mmap选择地图的位置(在没有MAP_FIXED标记的情况下调用),则会选择sbrk预订以外的区域。
  • 因此,在正常使用中,sbrkmmap不会相互干扰。此外,无论实现malloc使用哪种实现,它都应该接受它获得的内存并将其合并到数据库中而不会出现问题,无论是从sbrk还是从mmap获取内存还是从其他地方获取内存。并且它不应干扰程序对sbrkmmap的独立正常使用。
  • 如果您使用mmap致电MAP_FIXED并指定保留区域sbrk中的地址,那么mmap将在那里映射内存。
  • 如果您继续在sbrk之后再次呼叫mmap,则sbrk将返回成功,即使新的中断地址与使用mmap映射的内存重叠。此时,您的程序可能已损坏。

因此,将mmapMAP_FIXED一起使用是不明智的,除非您有充分的理由知道您指定的地址是可以的。

答案 1 :(得分:1)

堆和堆栈之间的简单划分是一种简化。现代操作系统支持大型虚拟地址空间,并且进程可以看到许多独立的内存区域。虽然这些区域是同一地址空间的一部分,但它们并不是连续的,它们中有漏洞。地址mmap()返回的是众多漏洞之一:它可能位于堆栈之后,堆栈之后,堆之前 - 只要这些区域永远不会满足,它就不会产生影响。 / p>

还要记住,在一个线程程序中没有单个堆栈,其中有多个与线程一样多。