在同一程序中使用 mmap 和 malloc 分配内存是否安全?

Is it safe to use mmap and malloc to allocate memory in same program?

目前我的理解是这样的:

  1. malloc 内部使用 sbrkbrk 通过增加堆顶来分配内存。
  2. mmap 以页的形式分配内存。

现在,假设 sbrk/malloc 的当前顶部是 0x001000。我使用 mmap 分配一个 4KB 的页面,该页面分配在 0x0020000。后来,如果我多次使用 malloc 并且因此它必须增加 sbrk top。那么,如果 top 达到 0x002000 怎么办?

所以,如果有人能澄清以下内容,那就太好了。

  1. 上述情况是否可能?
  2. 如果不是,请指出我对 mallocmmap 理解的缺陷。
  3. 如果是,我认为以这种方式使用它是不安全的。那么,有没有其他方法可以安全地使用两者?

谢谢。

  1. malloc 现在通常不会以这种方式实现...malloc 在旧实现中使用 sbrk(2),当时扩展数据段是向系统请求更多虚拟内存的唯一方法。如果可用,较新的系统会使用 mmap(2),因为当虚拟 space 足够大时它们允许更大的灵活性(每个 mmaped 块都作为请求它的进程的新数据段进行管理)。 sbrk(2) 扩展和收缩数据段,就像一个堆栈....所以你必须小心使用 sbrk(2) 以防你要将它与 sbrk 的实现混合使用分配。如果混合调用,malloc 的运行方式通常不允许您 return 使用 sbrk(2) 获得的任何内存...因此您只能使用它来安全地增长数据段。

  2. sbrk(2) 也以页为单位分配内存。自从分页虚拟内存出现后,几乎都o.s。分配以页面为单位进行。较新的系统甚至有不止一个页面大小(例如 4Kb 和 2Mb 大小),因此您可以从中受益,具体取决于应用程序。

  3. 随着 64 位系统的使用越来越多,分配地址 space 足够大以允许两种机制共存是没有问题的。这对于多堆 malloc 实现来说是一个优势,因为内存是独立分配和释放的,永远不会按照 LIFO 分配顺序。

Malloc 使用不同的方法分配内存,但实现通常尽量不干扰用户 sbrk(2) 使用。您必须小心,也就是说,如果您在 sbrk(2) malloc 系统中将 malloc(3) 调用与 sbrk(2) 混合使用。那么您 运行 有 sbrk(2) 遍历 malloc 调整后的数据段并破坏 malloc 内部数据结构的风险。如果您正在使用 malloc 的 sbrk(2) 实现,您最好不要自己使用 sbrk(2)

最后,为了回答您的问题,mmap(2) 分配内存与 malloc(3) 一样,因此 malloc 不会,也不必知道您为自己使用而分配的内存mmap(2).