目前我的理解是这样的:
malloc
在内部使用sbrk
和brk
通过增加堆顶来分配内存。mmap
以页的形式分配内存。
现在,假设 sbrk/malloc
的当前顶部是 0x001000
。我使用 mmap
分配了一个 4KB 的页面,该页面分配在 0x0020000
处。后来,如果我多次使用 malloc
并且因此它必须增加 sbrk
top。那么,如果 top 到达 0x002000
怎么办?
所以,如果有人能澄清以下内容,那就太好了。
- 上述情况是否可能?
- 如果不是,请指出我对
malloc
和mmap
理解的缺陷。 - 如果是,我认为以这种方式使用它是不安全的。那么,有没有其他方法可以安全地使用这两者?
谢谢。
最佳答案
malloc 现在通常不会以这种方式实现...malloc 在旧实现中使用
sbrk(2)
,当时扩展数据段是向系统请求更多虚拟的唯一方法内存。如果可用,较新的系统会使用mmap(2)
,因为当虚拟空间足够大时它们允许更大的灵 active (每个mmap
ed block 都作为一个新的数据段进行管理处理请求它)。sbrk(2)
扩展和收缩数据段,就像一个堆栈....所以你必须小心使用sbrk(2)
以防你要将它与 malloc 的sbrk
实现混合使用。如果混合调用,malloc 的运行方式通常不允许您返回通过sbrk(2)
获得的任何内存...因此您只能使用它来安全地增长数据段。sbrk(2)
也以页为单位分配内存。自从分页虚拟内存出现以来,几乎所有的 o.s.分配以页面为单位进行。较新的系统甚至有不止一个页面大小(例如 4Kb 和 2Mb 大小),因此您可以从中受益,具体取决于应用程序。随着 64 位系统的使用越来越多,分配足够大的地址空间以允许两种机制共存是没有问题的。这对于多堆 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)
分配的内存。
关于c - 在同一程序中使用 mmap 和 malloc 分配内存是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58232038/