总是在 mmap 中为常规文件添加 MAP_NORESERVE 标志?

Always add MAP_NORESERVE flag in mmap for a regular file?

根据mmapmanual

MAP_NORESERVE

Do not reserve swap space for this mapping. When swap space is reserved, one has the guarantee that it is possible to modify the mapping. When swap space is not reserved one might get SIGSEGV upon a write if no physical memory is available.

据我了解,如果将常规文件映射到虚拟地址范围,则不需要任何交换 space。只有 MAP_ANONYMOUS 可能需要一些交换 space.

那么,对于常规文件总是在 mmap 中添加 MAP_NORESERVE 标志是否正确?

更新:

更具体地说,当使用 MAP_SHARED 时,总是在 mmap 中为常规文件添加 MAP_NORESERVE 标志是否正确?

To my understanding, if a regular file is mapped into the virtual address range, there is no need for any swap space. Only MAP_ANONYMOUS may need some swap space.

这取决于 mmap 标志。如果使用 MAP_PRIVATE 映射常规文件,则内存区域会从文件 初始化 ,但不会 由文件 支持。如果系统决定换出其任何页面,则系统将需要交换 space 以进行此类映射。

So, is it correct to always add MAP_NORESERVE flag in mmap for a regular file?

为任何映射指定 MAP_NORESERVE 并非 不正确 。这只是一个问题,您希望对程序行为有什么保证。

此外,您似乎从错误的方向看待这个问题。如果一个特定的映射永远不需要 swap space 那么系统将不会为它保留 swap space,不管标志是什么。在这种情况下使用 MAP_NORESERVE 并没有什么坏处,但它也无济于事,那么有什么意义呢?

另一方面,如果您想确保映射不会因使用 MAP_NORESERVE 而失败,那么最合适的做法是避免使用该标志。如果你愿意,你可以完全忽略它的存在,事实上,如果你想要最大的可移植性,你应该这样做,因为 MAP_NORESERVE 是一个 Linux 扩展,没有被 POSIX.[=27= 指定]


更新:

据我了解,您断言您可以重复观察到现有文件的现有范围成功映射 MAP_SHARED 以要求 MAP_NORESERVE。也就是说,仅在是否指定 MAP_NORESERVE 方面有所不同的两次此类映射尝试将以您可以预测和可靠地重现的方式为您产生不同的结果。

我觉得这令人惊讶,甚至令人怀疑。我不希望页面 table 映射到常规文件的现有区域的进程虚拟地址 space 的页面与交换 space 有任何关联,因此我不希望系统在建立映射时尝试为此类页面保留任何交换 space,尽管有标记。如果您真的观察到不同的行为,那么我会将其归因于库或内核错误,您应该就此提出问题。

例如,考虑 GNU libc 手册,它明确指出 a memory mapping can be larger than physical memory and swap space,但根本没有记录 Linux-specific MAP_NORESERVE

话虽如此,为任何给定的内存映射指定 MAP_NORESERVE 并不是 不正确的 (在 Linux 上)。但是,我希望它对于常规文件的现有区域的 MAP_SHARED 映射毫无意义,因此我认为常规使用该标志进行此类映射的做法不是很好 - 更不用说最佳实践了。另一方面,如果指定该标志可以解决库或内核错误,否则会干扰建立某些映射,那么我看不出有什么特别的理由避免这样做,但我希望每次这样的使用都附有解释原因的文档评论使用该标志。