【问题标题】:Benefits of reserving vs. committing+reserving memory using VirtualAlloc on large arrays在大型数组上使用 VirtualAlloc 保留与提交+保留内存的好处
【发布时间】:2012-05-16 16:46:47
【问题描述】:

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

除非/直到实际访问虚拟地址,否则不会分配实际的物理页面。

我的实验证实了这一点:我可以保留和提交几 GB 的内存,而不会增加我的进程的内存使用量(如任务管理器中所示);只有当我实际访问内存时才会分配实际内存。

现在我看到了很多例子,他们认为应该保留大部分地址空间,然后逐页提交内存(或在一些更大的块中,取决于应用程序的逻辑)。然而,正如上面所解释的,在访问内存之前似乎并没有提交内存。因此,我想知道逐页提交内存是否有任何真正的好处。事实上,由于许多系统调用实际提交内存,逐页提交内存实际上可能会减慢我的程序速度。如果我一次提交整个区域,我只需为一次系统调用付费,但内核似乎足够聪明,实际上只分配我实际使用的内存。

如果有人能向我解释哪种策略更好,我将不胜感激。

【问题讨论】:

    标签: winapi memory-management virtual-memory virtualalloc


    【解决方案1】:

    不同之处在于提交“支持”页面文件的内存。举个例子:

    1. 假设有 2GB 的物理内存和 2GB 的交换空间(假设为此目的是固定大小的交换空间)。
    2. 预留 6GB - 好的。
    3. 先提交 2GB - 好的。
    4. 提交剩余的 4GB - 失败。
    5. 将交换文件扩展至 8GB
    6. 提交剩余的 4GB - 成功。

    使用 MEM_COMMIT 的原因主要是为了抑制运行时错误(应用程序稳定性)。如果您有一个按需提交页面的进程,那么如果它超过可用的内存+交换量,那么提交过程中总是有可能失败。当页面文件支持内存时,您就有strong保证该内存从现在到您释放它为止都可以使用。

    选择哪种方式有很多原因,我认为没有任何完美的科学可以决定哪种方式。仅 MEM_RESERVE 仅需要用于非常大的稀疏数组场景,例如:利用率最高为 25-33% 的多 GB 数组(一种用于加速哈希表等的流行技术)。

    几乎所有其他东西都是灰色区域,您可能会采取任何一种方式——预先 MEM_COMMIT 将使您自己的应用程序更加稳定,并且基本上将其优先于物理内存,而不是可能按需分配的竞争应用程序。 (如果您先抓住内存,那么当物理内存耗尽时,您的应用程序将是最后一个存在)同时,如果您实际上并没有使用所有内存,那么您最终可能会限制您的多任务处理潜力客户端的机器或通过不断增长的页面文件造成不必要的磁盘空间浪费。

    【讨论】:

    • 惊人的直接、简洁和出色的答案。违反(bah-humbug)“避免不必要的感谢!”的合理案例规则...
    猜你喜欢
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 2014-03-15
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多