macOS 相当于保留内存而不对提交限制收费

macOS equivalent of reserving memory without charging against commit limit

我经常需要可以按需增长的大型连续虚拟地址区域 space。在 Windows 上,我用 MEM_RESERVE 和一个 dwSize 参数调用 VirtualAlloc,我认为这个参数比该区域合理可能永远需要增长的参数大,然后提交根据需要一次一页。这不仅会延迟将页面映射到物理内存,直到它们被访问为止(这也可以从一开始就提交整个区域),它还会推迟根据系统提交限制对页面收费。这样,该程序就不会限制其他程序为了它尚未使用并且可能永远不会使用的内存而允许提交多少内存。基本上,我想处理我的程序的内存管理,如果用户的需求需要它,原则上允许它消耗大量内存,同时允许其他程序在他们首先需要它时拥有该内存。

有人 already asked macOS 是否有等同于 VirtualAllocMEM_RESERVE 的问题。答案表明 mmapMAP_ANON | MAP_PRIVATE 大致相同。我想知道的是,macOS 是否有等同于 Windows 提交限制,并且 mmap,使用正确的标志调用,表现得像我的 VirtualAlloc 用法一样不收费限制?

编辑:其他人 asked 关于 Linux 的类似问题,也有人建议 mmap。答案表明,在该平台上,最初使用 PROT_NONE 映射区域并在需要页面时添加所需的权限是必要的,以防止未使用的页面计入提交限制。缺乏更好的文档说明为什么在 macOS 中允许映射内存超过可用物理内存(完全没有提交限制?某种像 Linux 这样的过度提交功能?),我想我也可以应用相同的 PROT_NONE 以防万一。至少这意味着如果我也选择支持该平台,我将能够为 Linux 重用相同的代码。

我不认为 macOS 有系统提交限制。我在 Mach APIs 中找不到类似的东西,这是我期望的低级 VM API。同样,我在 sysctl -a 的输出中没有看到类似的内容,它报告了许多其他 VM 详细信息和统计信息。

我可以肯定地告诉你,我已经在 64 位进程(它有一个 46 位用户地址 space)中保留了全部未使用的 space。也就是说,不到 128TiB。

您可以通过重复 mmap() 大尺寸的调用来复制它,直到它们失败,将尺寸减半,然后重复,直到您的尺寸缩小到 1 页。然后,在进程暂停的情况下,对其应用 vmmap -w -interleaved <pid> 以查看其分配。