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

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

我无法得到的是这些API对VirtualAlloc()加上标志MEM_RESETMEM_RESET_UNDO ,以及这些细微的差别是什么。

对于OfferVirtualMemory() ,MSDN认为它与VirtualAlloc() + MEM_RESET非常相似,不同之处在于它从工作集中删除页面,并限制对页面的进一步访问。

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

如果这是真的,那么当然,页面将从进程的工作集中被移除,因为即使进程保持分配的虚拟地址,并且看到它们“提交”,它们也基本上被释放。

现在我们来看看DiscardVirtualMemory() :这里MSDN没有提到MEM_RESET标志,但是如果我读了这个API的描述,它看起来和VirtualAlloc() + MEM_RESET

那么,有没有人知道这些API之间是否存在一些差异,以及这些细微差别的恰当用例是什么? 如果他们引入了像DiscardVirtualMemory()这样的新的API,那么与旧的方法应该有一些区别。

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

DiscardVirtualMemory在MSDN上

当应用程序再次访问内存区域时,后备RAM将被恢复,并且内存的内容是不确定的。

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

  • 当你访问它的时候,有些东西可能仍然存在
  • 当这些页面提交时允许给你垃圾初始化页面
  • 如果机器实际上受限于内存,有些页面可能有时会被初始化为零

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

这使得窗口可以减少压缩页面的压力,当程序想要变得更好,并告诉窗口它可以丢弃一些释放的内存范围。