【问题标题】:Does VirtualFree unlock VirtualLock?VirtualFree 会解锁 VirtualLock 吗?
【发布时间】:2016-06-25 23:03:31
【问题描述】:

我正在重写相当老的 c++ 代码,偶然发现了内存管理部分。

更具体地说,“需要”的内存首先以类似于

的方式分配
int* Buffer;
int numPoints=80000;
Buffer = (int*)VirtualAlloc(NULL, numPoints* sizeof(int), MEM_COMMIT, PAGE_READWRITE);
VirtualLock(Buffer,numPoints * sizeof(int));

但是,缓冲区仅使用VirtualFree 释放,而不是VirtualUnlock

那么,第一个问题: VirtualFree 会调用 VirtualUnlock 吗?

此外,我还阅读了一些关于VirtualLock 的信息。在我的代码中,它显然用于提高性能,因为很多非常大的数组被使用和访问非常频繁,部分甚至被绘制为 2 fps 左右的图形......但是,我读到了 1. Virtuallock可能会降低系统性能,最终再次减慢一切速度 2. Virtuallock 并没有真正提高大型缓冲区的性能。后一个语句在此处使用 strassen HBC (https://software.intel.com/de-de/forums/intel-threading-building-blocks/topic/276995) 进行了测试。

因此,最后我决定反对VirtualLock,但https://msdn.microsoft.com/de-de/library/windows/desktop/aa366895(v=vs.85).aspx 声明VirtualLock 确保对该区域的后续访问不会导致页面错误。这是否意味着,注释掉 VirtualLock 会使像 *(buffer+10)=1 这样的访问失败或产生页面错误(假设缓冲区有超过 11 个分配点)?

所以第二个问题是: 我可以安全地丢弃锁定内存而不会使数组访问面临页面错误或崩溃的危险吗?

【问题讨论】:

  • 很难猜到你自己怎么想不通。做对了从来没有错,做对了,你不必去发现。当然,VirtualLock() 在具有千兆字节 RAM 的现代机器上变得毫无意义。
  • @HansPassant 好吧,请耐心等待我仍然没有看到它。^^ 我是否正确理解了您的评论,virtualFree 没有调用 virtualLock?另外,我确实分配了 1-2 GB RAM 之类的东西,所以在现代机器上锁定 RAM 仍然没有关系吗?
  • @HansPassant,无法找到表达我最强烈反对的语言。当然,VirtualLock 仍然非常有效。

标签: c++ memory-management


【解决方案1】:

是的。 VirtualFree(MEM_RELEASE/MEM_DECOMMIT) 如果该区域已被 VirtualLock() 锁定,则解锁该区域。

而且 VirtualLock() 仍然很有用,因为它可以更快地访问。 (此外,有些任务需要非分页内存,就像重叠 IO 一样。) 如果没有 VirtualLock(),无论物理内存大小如何,都不能保证超过数百兆字节的缓冲区是非分页的,因为操作系统倾向于为内核的非分页池和 IO 缓存保留物理内存。

顺便说一句,您需要 SetProcessWorkingSetSize() 来保护您自己的进程的物理内存。 如果没有足够的进程工作集,VirtualLock() 可能会失败。

恕我直言,为通用软件(在各种系统内存大小未知的系统上运行)锁定巨大的内存区域并不是一个好主意,因为它会从操作系统的关键部分窃取物理内存。 将其用于在专用机器上运行的软件(例如专用服务器或专用编码 PC)。

【讨论】:

  • 出于安全原因,这是最有用的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多