我正在重写相当老的c++代码,偶然发现了内存管理部分。
更具体地说,首先以类似于以下方式分配内存“需要”
int* Buffer;
int numPoints=80000;
Buffer = (int*)VirtualAlloc(NULL, numPoints* sizeof(int), MEM_COMMIT, PAGE_READWRITE);
VirtualLock(Buffer,numPoints * sizeof(int));
但是,仅使用
VirtualFree
而不是VirtualUnlock
释放Buffer。因此,第一个问题是: 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()锁定,则VirtualFree(MEM_RELEASE / MEM_DECOMMIT)会解锁该区域。
而且VirtualLock()仍然有用,因为它使访问速度更快。
(此外,某些任务需要非页面内存,例如重叠的IO。)
如果没有VirtualLock(),则无论物理内存大小如何,都无法保证超过数百兆字节的字节缓冲区是非分页的,因为O.S倾向于为内核的非分页池和IO缓存保留物理内存。
顺便说一句,您需要SetProcessWorkingSetSize()来保护您自己的进程的物理内存。
如果没有足够的进程工作集,VirtualLock()可能会失败。
恕我直言,锁定通用软件的巨大内存区域(在运行于未知系统内存大小的各种系统上运行)不是一个好主意,因为它从操作系统的关键部分窃取了物理内存。
将其用于专用计算机(例如专用服务器或专用编码PC)上运行的软件。