我正在编写一个C程序,它基本上适用于非常大的数组.在
Windows上,我使用VirtualAlloc为我的阵列分配内存.现在我完全理解使用VirutalAlloc保留和提交内存之间的区别;但是,我想知道将内存逐页提交到保留区域是否有任何好处.特别是,MSDN(
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366887(v=vs.85).aspx)包含MEM_COMMIT选项的以下说明:
除非/直到实际访问虚拟地址,否则不会分配实际物理页面.
我的实验证实了这一点:我可以保留并提交几GB的内存,而不会增加我的进程的内存使用量(如任务管理器中所示);实际内存只有在我实际访问内存时才会被分配.
现在我看到了很多例子,他们认为应该保留一大部分地址空间,然后逐页提交内存(或者在一些更大的块中,这取决于应用程序的逻辑).但是,如上所述,在访问内存之前,似乎没有提交内存;因此,我想知道在逐页提交内存方面是否有任何实际好处.实际上,由于许多系统调用实际存储内存,逐页提交内存实际上可能会减慢我的程序速度.如果我一次提交整个区域,我只支付一个系统调用,但内核似乎足够智能,实际上只分配我实际使用的内存.
如果有人能向我解释哪种策略更好,我将不胜感激.
最佳答案 不同之处在于提交内存与页面文件“后退”.举个例子:
>给出2GB的物理内存和2GB的交换(为此目的采用固定大小的交换).
>预留6GB – 好的.
>首先提交2GB – 好的.
>提交剩余的4GB – 失败.
>将交换文件扩展到8GB
>提交剩余的4GB – 成功.
使用MEM_COMMIT的原因主要是运行时错误抑制(应用程序稳定性).如果您有一个按需提交页面的进程,那么如果超出可用的内存交换量,那么沿途提交总是有可能失败.当页面文件支持内存时,您可以确保从现在开始直到释放内存为止.
这种方式有很多理由,我认为没有任何完美的科学来决定哪种方式.仅对于非常大的稀疏阵列场景才需要MEM_RESERVE,例如:多千兆字节阵列,其利用率最高为25-33%(一种用于加速哈希表的流行技术等).
几乎所有其他东西都是灰色区域,你可以选择其中任何一种方式 – MEM_COMMIT预先设置会使你自己的应用程序更加稳定,并且基本上优先考虑可能按需分配的竞争应用程序的物理内存. (如果你先抓住ram然后你的应用程序将是物理内存耗尽时的最后一个站点)同时,如果你实际上没有使用所有那些ram那么你可能最终限制你的多任务潜力客户端的机器或通过不断增长的页面文件导致不必要的浪费的磁盘空间.