使用VirtualAlloc在大型数组上预留内存与提交+预留内存相比的优势

7
我正在编写一个与非常大的数组一起工作的C++程序。在Windows上,我使用VirtualAlloc为我的数组分配内存。现在我完全理解了使用VirutalAlloc保留和提交内存之间的区别;但是,我想知道将内存逐页提交到保留区域中是否有任何好处。特别是,MSDN(http://msdn.microsoft.com/en-us/library/windows/desktop/aa366887(v=vs.85).aspx)中包含了MEM_COMMIT选项的以下解释:

实际物理页面直到虚拟地址被访问才分配。

我的实验证实了这一点:我可以保留和提交数GB的内存而不增加进程的内存使用量(如任务管理器所示);只有当我实际访问内存时才分配实际内存。
现在我看到很多示例都在争论应该先保留地址空间的大部分,然后逐页(或按某些较大的块,具体取决于应用程序的逻辑)提交内存。然而,如上所述,在访问内存之前似乎不会提交内存;因此,我想知道逐页提交内存是否有任何真正的好处。事实上,逐页提交内存可能会由于实际提交内存的许多系统调用而使我的程序变慢。如果我一次性提交整个区域,我只需要支付一个系统调用,但内核似乎足够聪明,只分配我实际使用的内存。
我希望有人能解释一下哪种策略更好。
1个回答

9
区别在于“提交”将内存支持到页面文件。以下是举例:
1. 给定2GB物理内存和2GB交换(为此目的假定固定大小的交换)。 2. 保留6GB - 没问题。 3. 首先提交2GB - 没问题。 4. 提交剩余的4GB - 失败。 5. 扩展交换文件到8GB 6. 提交剩余的4GB-成功。
使用MEM_COMMIT的原因主要是运行时错误抑制(应用程序稳定性)。如果您有一个按需提交页面的进程,那么一旦超过可用内存+交换的数量,提交沿途可能会失败。当内存由页面文件支持时,您可以确信这些内存从现在起到释放时都可供使用。
选择使用MEM_RESERVE或MEM_COMMIT存在很多原因,并且我认为没有任何完美的科学方法来决定哪种方法更好。 MEM_RESERVE仅在非常大的稀疏数组场景下需要,例如最多具有25-33%利用率的多千兆字节数组(加速哈希表等流行技术)。
其他几乎所有东西都是灰色地带,您可能可以选择其中之一--提前使用MEM_COMMIT会使您自己的应用程序更加稳定,并基本上将其优先级设置为优先使用竞争应用程序可能按需分配的物理内存。 (如果您先占用内存,则在物理内存耗尽时您的应用程序将是最后一个留下的)同时,如果实际上没有使用所有内存,则可能会限制客户机的多任务潜力或通过增加页面文件而导致不必要的浪费磁盘空间。

惊人的直接、简洁和精彩的回答。这是一个充分证明违反“避免不必要的感谢!”规则的案例... - Glenn Slayden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接