Windows 8.1 / Server 2012RC2刚刚推出了虚拟内存pipe理的新API: OfferVirtualMemory()
, ReclaimVirtualMemory()
, DiscardVirtualMemory()
,它们的用法非常简单,只需查看它们的名称即可。
我无法得到的是这些API对VirtualAlloc()
加上标志MEM_RESET
和MEM_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_DONTNEED
和MADV_WILLNEED
的应用程序,那么模仿这个POSIX行为的最好方法是什么? 到目前为止,我使用了MADV_DONTNEED
VirtualAlloc()
+ MEM_RESET_UNDO
和MADV_WILLNEED
VirtualAlloc()
+ MADV_WILLNEED
。 没关系,或者我可以用这些新的API做得更好?
DiscardVirtualMemory在MSDN上
当应用程序再次访问内存区域时,后备RAM将被恢复,并且内存的内容是不确定的。
如果我在两行之间阅读,那就是说,
如果您使用较旧的API重置虚拟地址范围,则不会发生这种情况。 在这种情况下,保证在您稍后访问这些页面时提供零初始化页面。
这使得窗口可以减少压缩页面的压力,当程序想要变得更好,并告诉窗口它可以丢弃一些释放的内存范围。