`VirtualAlloc()` 的 `MEM_RESERVE` 标志今天真的有用吗?

Is the `MEM_RESERVE` flag of `VirtualAlloc()` really useful today?

首先,让我说,我非常了解 VirtualAlloc() 的工作原理以及现代操作系统的虚拟内存设施通常如何工作。

表示,使用 VirtualAlloc() Windows API 的 MAP_RESERVE flag,without using also MEM_COMMIT,今天有实际用途吗?

我的意思是,当我用 MEM_RESERVE|MEM_COMMMIT 调用 VirtualAlloc() 时,我既保留又提交页面,但是 我知道操作系统会真正分配页面只有当我尝试写入它们时。 这种优化几乎发生在所有现代操作系统上。

所以,考虑到这个优化,如果我用 MEM_RESERVE 调用 VirtualAlloc(),然后用 MEM_COMMIT 调用它几次来提交页面,相同 仅调用一次 VirtualAlloc() 的结果,指定 MEM_RESERVE|MEM_COMMIT ?

因为仅指定 MEM_RESERVE 将只保留页面边界地址,而不会提交实际页面,但是 MEM_RESERVE|MEM_COMMIT 将只保留+提交我写入的页面,而不是使用 MEM_RESERVE 一个人,浪费今天的时间? 仅 1 使用 MEM_RESERVE|MEM_COMMIT 调用 VirtualAlloc() 我基本上可以获得使用 MEM_RESERVE 调用 VirtualAlloc() 1 次并调用的相同结果MEM_COMMIT.

几次

作为我所说的证据,我注意到 MEM_RESERVE 设施在使用 mmap(2) 系统调用的 Unices/POSIX 系统中根本不存在。 你也可以 "commit" 一大块页面调用 mmap(2) 一次,然后只有当你写入它们时页面才会真正分配,所有这些都由操作系统优化。

那么,单独使用 MEM_RESERVE 是否只是过去的事情,只有当内存页面是一种宝贵的资源时才有用,所以今天没用了? 或者,单独使用这个标志(然后用 MEM_COMMIT 调用 VirtualAlloc() N 次)仍然有一些我缺少的实际用途?

当您提交内存时,内存管理器不会立即为您分配实际页面,但是it does count them towards the total number available.内存管理器永远不会提交比实际存在的页面更多的页面,并且保证您在访问已提交页面,内存就在那里。

MEM_RESERVE的目的是分配虚拟内存地址。您可以根据需要保留任意多的地址 space,在 64 位系统上最多可以保留很多 TB,即使您没有多少 TB 的实际 space.

默认情况下,Linux 不会将分配限制为实际可用的 space 数量。此“功能”称为 overcommit。这意味着在 Linux 上没有单独的保留和提交步骤。如果您想在 Linux、another question recommends mmapping an area with no permissions..

上保留地址 space

除了之前的答案,这里引用了 Microsoft docs:

As an alternative to dynamic allocation, the process can simply commit the entire region instead of only reserving it. Both methods result in the same physical memory usage because committed pages do not consume any physical storage until they are first accessed. The advantage of dynamic allocation is that it minimizes the total number of committed pages on the system. For very large allocations, pre-committing an entire allocation can cause the system to run out of committable pages, resulting in virtual memory allocation failures.