用于虚拟内存管理的新Windows 8.1 API:`DiscardVirtualMemory()`vs`VirtualAlloc()`和`MEM_RESET`和`MEM_RESET_UNDO`

时间:2015-08-15 10:22:18

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

Windows 8.1 / Server 2012RC2刚刚推出了用于虚拟内存管理的新API:OfferVirtualMemory()ReclaimVirtualMemory()DiscardVirtualMemory(),只需查看其名称即可使用它们非常简单。< / p>

我无法获得的是这些API如何对VirtualAlloc()加上标记MEM_RESETMEM_RESET_UNDO起作用,以及哪些细微差别。

对于OfferVirtualMemory(),MSDN表示与VirtualAlloc() + MEM_RESET非常相似,只是它会从工作集中删除页面,并限制对页面的进一步访问。

所以,基本上它限制了对页面的访问,如果我想再次访问这些页面,我必须调用ReclaimVirtualMemory(),这很好,但不应该MEM_RESET还从工作集中删除页面? 不应该MEM_RESET充当MADV_DONTNEED的POSIX madvise(2)标记,它基本上会删除过程中的网页。页面表,如果我将来再次访问这些页面,访问将产生一个软错误,这些页面将再次重新分配,初始化为零。

如果这是真的,当然页面会从进程的工作集中删除,因为它们基本上会被释放,即使进程保留了已分配的虚拟地址,并且看到它们已经提交了#34;。 / p>

现在,让我们看看DiscardVirtualMemory():这里MSDN没有提及MEM_RESET标志,但如果我读了这个API的描述,那么它似乎真的VirtualAlloc() + MEM_RESET相同。

那么,是否有人知道这些API之间是否存在某些差异,以及这些微妙差异的正确用例是什么? 如果他们引入了一个像DiscardVirtualMemory()那样的新API,那么旧方法应该会有所不同。

如果我想从POSIX移植使用madvise(2) MADV_DONTNEEDMADV_WILLNEED的应用程序,那么模仿此POSIX行为的最佳方法是什么?到目前为止,我使用VirtualAlloc() + MEM_RESET用于MADV_DONTNEEDVirtualAlloc() + MEM_RESET_UNDO用于MADV_WILLNEED。 没关系,或者我可以用这些新API做得更好?

1 个答案:

答案 0 :(得分:3)

DiscardVirtualMemory on MSDN

  

当应用程序再次访问内存区域时,   恢复后备RAM,并且内存的内容未定义。

如果我在两行之间阅读,那就说,

  • 当您访问它时可能仍然存在的一些内容
  • 允许在这些页面提交时为您提供垃圾初始化页面
  • 如果机器实际上被限制为内存,有些页面有时可能会初始化为零

如果使用旧版API重置虚拟地址范围,则不会发生这种情况。在这种情况下,可以保证在以后访问这些页面时提供零初始化页面。

当程序想要更好的时候,这可以让windows对归零页面池施加更小的压力,并告诉windows它可以丢弃一些释放的内存。