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

时间:2015-07-28 09:14:32

标签: c winapi memory memory-management virtual-memory

首先,我要说的是,我非常清楚VirtualAlloc()如何工作以及现代操作系统的虚拟内存设施如何工作。

说,使用MAP_RESERVE Windows API的VirtualAlloc()标志,还使用MEM_COMMIT,今天有一些实际用途吗?

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

因此,考虑到这一优化问题,如果我使用VirtualAlloc()调用MEM_RESERVE,然后我使用MEM_COMMIT多次调用它来提交页面,则不是相同仅调用VirtualAlloc()一次的结果,指定MEM_RESERVE|MEM_COMMIT

由于仅指定MEM_RESERVE将仅保留页面边界地址,而不提交实际页面,但是MEM_RESERVE|MEM_COMMIT将仅保留+提交我写入的页面,而不是使用{{1}单独,今天浪费时间? 只有 1 使用MEM_RESERVE调用VirtualAlloc()我基本上可以获得与MEM_RESERVE|MEM_COMMIT一次调用VirtualAlloc()并将其称为几个N的相同结果时间MEM_RESERVE

作为我所说的内容的证明,我注意到MEM_COMMIT工具在使用MEM_RESERVE系统调用的Unices / POSIX系统中根本不存在。 在那里你可以"提交"一大块页面调用mmap(2)一次,然后只有在你写入页面时才真正分配页面,这些页面都是由操作系统优化的。

所以,单独使用mmap(2)只是旧时的事情只有在内存页面是宝贵的资源时才有用,所以今天没用? 或者,单独使用此标记(然后使用MEM_RESERVE调用VirtualAlloc() N次)仍有一些我遗漏的实际用途?

2 个答案:

答案 0 :(得分:3)

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

MEM_RESERVE的目的是分配虚拟内存地址。您可以根据需要保留尽可能多的地址空间,即使您没有多太字节的实际空间,也可以在64位系统上保留多达数TB的数据。

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

答案 1 :(得分:0)

除了前面的答案,这里还有Microsoft docs的引文:

作为动态分配的替代方法,该过程可以简单地提交整个区域,而不仅仅是保留它。 这两种方法导致相同的物理内存使用,因为已提交的页面在首次访问之前不会消耗任何物理存储。动态分配的优势在于,它可以最大程度地减少系统上已提交页面的总数。对于非常大的分配,预先提交整个分配会导致系统用尽可提交页面,从而导致虚拟内存分配失败。