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

C++ 用于虚拟内存管理的新Windows 8.1 API:`DiscardVirtualMemory()`vs`VirtualAlloc()`和`MEM_RESET`和`MEM_RESET_UNDO`,c++,windows,winapi,memory-management,virtual-memory,C++,Windows,Winapi,Memory Management,Virtual Memory,Windows 8.1/Server 2012RC2刚刚为虚拟内存管理引入了新的API:OfferVirtualMemory(),ReceiveVirtualMemory(),DiscardVirtualMemory(),它们的用法非常简单,只需查看它们的名称即可 我无法理解的是,这些API是如何对抗VirtualAlloc()加上MEM\u RESET和MEM\u RESET\u UNDO标志的,它们之间的细微差别是什么 对于OfferVirtualMemory(),MSDN表示这与Virtu

Windows 8.1/Server 2012RC2刚刚为虚拟内存管理引入了新的API:
OfferVirtualMemory()
ReceiveVirtualMemory()
DiscardVirtualMemory()
,它们的用法非常简单,只需查看它们的名称即可

我无法理解的是,这些API是如何对抗
VirtualAlloc()
加上
MEM\u RESET
MEM\u RESET\u UNDO
标志的,它们之间的细微差别是什么

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

因此,它基本上限制了对页面的访问,如果我想再次访问这些页面,我必须调用
receiveVirtualMemory()
,这很好,但是
MEM\u RESET
是否也应该从工作集中删除页面?
MEM_RESET
不应该充当
madvise(2)
的POSIX
MADV_DONTNEED
标志,它基本上从进程的页面表中删除页面,如果我以后再次访问这些页面,访问将生成软故障,这些页面将再次重新分配,并初始化为零

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

现在,让我们来看看
DiscardVirtualMemory()
:这里MSDN没有提到
MEM\u RESET
标志,但是如果我阅读这个API的描述,它看起来确实与
VirtualAlloc()
+
MEM\u RESET
一样

那么,是否有人知道这些API之间是否存在一些差异,以及这些细微差异的适当用例是什么? 如果他们引入了一个全新的API,比如
DiscardVirtualMemory()
,那么应该与旧方法有所不同

如果我想从POSIX移植一个应用程序,它使用
madvise(2)
MADV\u DONTNEED
以及
MADV\u WILLNEED
,那么模仿这种POSIX行为的最佳方法是什么?到目前为止,我使用了
VirtualAlloc()
+
MEM\u RESET
用于
MADV\u DONTNEED
VirtualAlloc()
+
MEM\u RESET\u UNDO
用于
MADV\u WILLNEED
。 这样可以吗,或者我可以用这些新API做得更好?

当应用程序再次访问内存区域时 备份RAM已恢复,内存内容未定义

如果我读字里行间的话,那就是说

  • 当你访问它时,有些东西可能仍然存在
  • 当这些页面提交时,允许向您提供垃圾初始化页面
  • 如果机器实际上内存有限,某些页面有时可能会被零初始化
如果使用较旧的API重置虚拟地址范围,则不会发生这种情况。在这种情况下,可以保证在以后访问这些页面时提供零初始化页面


这使得windows可以在程序想要变得更加友好时,减少对归零页面池的压力,并告诉windows它可以丢弃一些释放的内存。

MEM_RESET不会强制将页面从工作集中删除,虽然如果需要减少工作组,它们可能是第一个被选择的。丢弃virtualMemory()和MEM_RESET之间的明显区别在于前者无法撤消。最合适的API选择可能取决于您的特定用例,对于所有场景都没有单一的最佳选择。使页面不可访问是一个显著的改进,当您意外地继续使用它们时,获得完全随机的AV并没有什么好处。我认为将它们从工作环境中移除只是一个副作用。但不要忘记,显然最重要的新特性是优先权。尤其是移动设备可以从中受益。@HansPassant是的,我同意你关于优先权的观点,通过设置那些页面不可用,这样的错误肯定会很快被发现。我认为Hans说得对,从工作集中删除页面可能只是使页面不可访问的副作用。丢弃virtualMemory()可能比
MEM_RESET
更有效,因为它不必是可逆的,但我不认为它更强大。请记住,从工作集中删除页面不会带来任何好处,如果有任何好处的话,那么当您最终重用地址空间时,由于额外的页面错误,很可能会降低性能。还要注意,您认为新API必须始终提供不同功能的假设是不正确的。新API的引入通常仅仅是因为程序员比旧API更容易正确使用。如果他们提供了一些额外的特性(比如优先级参数),那可能只是附带的好处。我猜这里就是这样。是的,这是一个非常有趣的观点。我同意你的看法。那么,您认为Windows通过添加这些API增加了更多的“精细度”吗?