gpt4 book ai didi

winapi - 在大型阵列上使用VirtualAlloc保留与提交+保留内存的优势

转载 作者:行者123 更新时间:2023-12-01 04:04:20 24 4
gpt4 key购买 nike

我正在编写一个本质上可以用于非常大的数组的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会使您自己的应用程序更加稳定,并且从本质上讲,它比可能按需分配的竞争应用程序更优先考虑物理内存。 (如果您先捕获内存,那么当物理内存耗尽时,您的应用程序将是最后一站)。同时,如果您实际上并没有使用所有内存,那么最终可能会限制您的多任务处理能力客户端的计算机或通过不断增长的页面文件造成不必要的磁盘空间浪费。

    关于winapi - 在大型阵列上使用VirtualAlloc保留与提交+保留内存的优势,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10494588/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com