【问题标题】:Is the `MEM_RESERVE` flag of `VirtualAlloc()` really useful today?`VirtualAlloc()` 的 `MEM_RESERVE` 标志今天真的有用吗?
【发布时间】:2015-10-18 18:12:40
【问题描述】:

首先,让我说我非常了解VirtualAlloc() 的工作原理以及现代操作系统的虚拟内存设施一般是如何工作的。

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

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

因此,考虑到这种优化,如果我用MEM_RESERVE 调用VirtualAlloc(),然后我用MEM_COMMIT 调用它几次来提交页面,不是 same 结果只调用一次VirtualAlloc(),指定MEM_RESERVE|MEM_COMMIT

由于仅指定MEM_RESERVE 将仅保留页面边界地址,而不提交真实页面,但是MEM_RESERVE|MEM_COMMIT 将仅保留+提交我写入的页面,不单独使用MEM_RESERVE,今天浪费时间? 只需 1MEM_RESERVE|MEM_COMMIT 调用VirtualAlloc(),我基本上可以获得相同的结果,即用MEM_RESERVE 调用VirtualAlloc() 1 次并用MEM_COMMIT 调用它N 次。

作为我所说的证明,我注意到 MEM_RESERVE 设施在使用 mmap(2) 系统调用的 Unices/POSIX 系统中根本不存在。 您还可以在那里“提交”一大块调用mmap(2) 的页面,然后只有在您写入页面时才会真正分配页面,所有这些都由操作系统优化。

那么,单独使用MEM_RESERVE 是否只是旧时的东西,只有当内存页面是宝贵的资源时才有用,所以今天没用? 或者,单独使用这个标志(然后用MEM_COMMIT 调用VirtualAlloc() N 次)仍然有一些我缺少的实际用途?

【问题讨论】:

  • stackoverflow.com/q/10494588/613130 区别在于交换文件的处理(如果那里的响应正确的话)
  • 在地址空间有限的 32 位系统上,我可以看到 MEM_RESERVE 本身仍然有用。在 64 位系统上可能没什么意义。

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


【解决方案1】:

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

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

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

【讨论】:

  • 是的,我猜这与交换空间、Linux 过量使用设施等有关。stackoverflow.com/questions/10494588/… 中的答案解释得很清楚。我知道MEM_RESERVE 基本上只在树结构中写入一个新节点,代表您保留的地址范围。然后当你提交时,操作系统会真正面对现实,并意识到它是否可以提交那些页面,检查内存,交换文件等。mmap(2)PROT_NONE+MAP_NORESERVE的方法非常有趣-谢谢。
【解决方案2】:

除了之前的回答,这里引用了Microsoft docs

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

【讨论】:

    猜你喜欢
    • 2014-11-19
    • 2021-03-16
    • 1970-01-01
    • 2016-01-27
    • 2015-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多