mmap 是否允许创建比物理内存量大得多的映射?

mmap 是否允许创建比物理内存量大得多的映射?

显然,mmap受到最大可用虚拟地址空间块的大小的限制。但假设我们有一个 64 位系统,对于大多数用途来说这几乎是无限的。我们还假设没有配置交换分区。

在匿名映射的情况下,大小必须限制为可用物理内存的总量。

但是,在文件支持的映射的情况下,我想知道是否存在基于物理内存量的限制,例如映射的大小最多可以是物理内存量的X倍?或者mmap只要不达到虚拟地址空间限制,就允许我将任意大的文件映射为单个块?例如,如果我有 32 GiB 的 RAM,我可以成功创建mmap1 TiB 的磁盘文件吗?

特别询问有关 Linux 的问题,以防万一。 (我尝试使用 64 GiB 文件,它似乎可以工作。不幸的是,我没有比这更多的可用磁盘空间。)

答案1

使用mmap()映射文件不会将文件复制到物理内存,因此没有理由限制它。只要整个文件能够用虚拟地址空间来表示,就可以进行映射。其工作原理是每个页面并不驻留在内存中,因此访问它会触发页面错误。内核透明地利用这个机会访问文件的该部分。这允许用户进程操作一个非常大的文件,而不需要做一堆效率低下 read()write(), 和seek()循环(尽管它仍然会导致上下文切换,如某物必须实际处理 VFS)。

请注意,匿名映射超过剩余物理内存,如果内存过量使用已启用,因为页表已设置,以便每个虚拟页指着物理的零页。任何读取都会返回零,但是写入会导致页面错误,内核需要找到一个空闲的物理页来存储数据,此时它可以更新页表。当然,这需要你有足够的物理内存+交换空间。过度使用是一种有用的优化,因为大多数内存分配器都会积极地为其堆请求内存,即使其中大部分未使用。

您甚至可以映射文件大于地址空间,但不是一次调用就能一次性全部完成mmap()


作为附录,即使在 64 位系统上,您也可能无法使用完整的 64 位地址空间:

$ grep -m1 "address sizes" /proc/cpuinfo 
address sizes   : 39 bits physical, 48 bits virtual

在该系统上,由于 48 位虚拟地址空间被分成两部分,因此您可以映射一个大小为 2 47 的文件字节或 128 TiB 的文件(实际上要小一些,因为一些地址空间已被使用)。

相关内容