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

Posted

技术标签:

【中文标题】用于虚拟内存管理的新 Windows 8.1 API:`DiscardVirtualMemory()` 与 `VirtualAlloc()` 和 `MEM_RESET` 和 `MEM_RESET_UNDO`【英文标题】:New Windows 8.1 APIs for virtual memory management: `DiscardVirtualMemory()` vs `VirtualAlloc()` and `MEM_RESET` and `MEM_RESET_UNDO` 【发布时间】:2015-11-08 12:27:20 【问题描述】:

Windows 8.1/Server 2012RC2 刚刚引入了用于虚拟内存管理的新 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()+@ 相同987654338@.

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

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

【问题讨论】:

MEM_RESET 不会强制将页面从工作集中删除,尽管如果需要减少工作集,它们可能是第一个选择的。 DiscardVirtualMemory() 和 MEM_RESET 之间的明显区别在于前者无法撤消。最合适的 API 选择可能取决于您的特定用例,没有适用于所有场景的最佳选择。 使页面无法访问是一项重大改进,当您不小心继续使用它们时获得完全随机的 AV 并没有什么好说的。我认为将它们从工作集中删除只是其副作用。但不要忘记,显然最重要的新特性是 priority 参数。尤其是移动设备可以从中受益。 @HansPassant 是的,我同意你的 priority 论点,通过将这些页面设置为不可用,肯定会很快发现类似的错误。 我认为 Hans 说得对,从工作集中删除页面可能只是使页面无法访问的副作用。而且 DiscardVirtualMemory() 可能比MEM_RESET 更有效,因为它不必是可逆的,但我认为它并不更强大。请记住,从工作集中删除页面不会带来任何好处,如果最终重用地址空间时出现额外的页面错误,则更有可能降低性能。 另请注意,您认为新 API 必须始终提供不同功能的假设是不正确的。引入新的 API 通常仅仅是因为程序员比旧 API 更容易正确使用它们。如果他们提供了一些额外的特性(比如优先级参数),这可能只是一个附带的好处。我怀疑这里就是这种情况。 【参考方案1】:

DiscardVirtualMemory on MSDN

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

如果我在字里行间读到,那就是,

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

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

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

【讨论】:

是的,这是一个非常有趣的观点。我同意你的看法。那么您是否认为 Windows 通过添加这些 API 增加了一些更细粒度的“好”?

以上是关于用于虚拟内存管理的新 Windows 8.1 API:`DiscardVirtualMemory()` 与 `VirtualAlloc()` 和 `MEM_RESET` 和 `MEM_RESET_UN的主要内容,如果未能解决你的问题,请参考以下文章

Windows phone 8.1 后台任务内存管理

windows中的虚拟内存管理技术是指使用啥来运行应用程序

如何将一个域名指向虚拟机Windows2003中的新云网站管理系统,并怎样从外部进行登录?请高手赐教。非常感谢

谁能概括一下windows是如何管理内存的?

微软已于10月底停止销售预装Windows 7/8.1的电脑

Windows 8.1下安装Mac OS X 10.8虚拟机