使用MAP_NORESERVE的mmap是否保留物理内存?

mmap文档在关于标志MAP_NORESERVE的说明如下。

不要为这个映射保留交换空间。 当交换空间被保留时,可以保证可以修改映射。 当交换空间未被保留时,如果没有可用的物理内存,则可以在写入时获得SIGSEGV。

我实际上想要的只是保留虚拟内存地址,并没有分配实际的物理内存。 这可以通过使用MAP_NORESERVE的mmap来完成吗? 如果我想要使用任何物理内存,我将使用MAP_NORESERVE通过mmap中的地址范围内的MAP_FIXED重新映射它。

总而言之,我希望内核不会为MAP_NORSERVE标志的mmap分配的内存预留任何物理页面。 它是否真的像这样工作,或者如果内核具有足够的物理内存,内核是否分配物理页面?

Mmap()是管理{地址,物理内存,磁盘块}之间关联的方法之一。这个关联的所有三个成员都是资源。 该关联保存在页表项(PTE)

mmap()实际上做了什么,是:

  • [也许]在用户进程中分配一个地址范围。 该范围必须由连续地址组成(不应与现有范围重叠)
  • 为请求的范围创建PTE并使它们指向地址范围内的页面
  • 让PTE指向文件mmap()
  • [也许]分配和预取(一些)页面
  • [也许]保留一些后备存储。

上述步骤中的很多(3/5)是可选的,并且取决于mmap()调用中提供的实际参数和标志。 (fd可以是-1:创建一个匿名映射,起始地址可以是NULL:mmap应该分配一个(以前)未使用的内存区域)

在调用mmap()之后,内核中的页面错误处理程序应该能够找出要执行的操作。 (附加物理RAM到页面;刷新和分离;分配和COW,…)

保留交换空间意味着调用者相信将来在任何时候都有足够的交换空间。 交换空间由所有进程共享,所以永远不能保证足够的交换空间。 预先分配它(或多或少)可以保证调用过程总是有足够的保证。 (当不是时:mmap()应该失败)

在Linux上,mmap只设置虚拟内存映射,无论您是否使用MAP_NORESERVE,在您触摸内存之前都不会分配物理内存。

MAP_FIXED与此无关,它会在您指定的虚拟(而非物理)地址处设置虚拟内存映射,或者如果在该地址处没有空间进行映射,将会失败。

只需使用正常的mmap() 。 任何实现了mmap的现代足够的操作系统(即过去,什么,1995年?)也实现了需求分页,而页面只有在实际写入时才会被保留。