我有一个使用大量内存映射文件的进程。
问题是这些文件保存在物理内存中,即使机器内存不足,其他进程也需要此内存。
我尝试使用SetProcessWorkingSetSize来限制进程工作集,但它没有帮助,进程的工作集不断增长超过最大值。
有没有更好的方法来限制进程的工作集?
我可以更改 Windows 的启发式方法来分页内存映射文件吗?
我有一个使用大量内存映射文件的进程。
问题是这些文件保存在物理内存中,即使机器内存不足,其他进程也需要此内存。
我尝试使用SetProcessWorkingSetSize来限制进程工作集,但它没有帮助,进程的工作集不断增长超过最大值。
有没有更好的方法来限制进程的工作集?
我可以更改 Windows 的启发式方法来分页内存映射文件吗?
最终使用蛮力 VirtualUnlock。
PROCESS_MEMORY_COUNTERS pmc;
if (GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
{
if (pmc.WorkingSetSize > MaxWorkingSetSize)
{
VirtualUnlock(FilePtr.pData, MaxWorkingSetSize);
UnmapViewOfFile(FilePtr.pData);
CloseHandle(FilePtr.hFileMap);
CloseHandle(FilePtr.hFile);
}
}
如果您发现具有内存映射文件的进程保留了很多这些页面,那么这意味着操作系统不需要丢弃任何内存映射区域以提供给其他进程。那么,你怎么知道其他进程实际上需要当前用于映射文件的内存呢?仅仅因为操作系统的物理内存不足就没有任何意义。其他进程必须要求内存以使操作系统删除您的映射页面并为它们提供 RAM。
因此,您的 mmap-I/O 进程似乎正在使您使用 RAM 频率较低的其他进程挨饿。一种方法是明智地将内存锁定在处于饥饿状态的进程中。查看用于 win32 的 VirtualLock。
我认为这种行为是由于 MMF(内存映射文件)的工作方式。看看这篇博客文章。它解释了 MMF 文件跳过 Windows 分页过程,因此不受页面文件的支持。相反,MMF 本身成为数据备份,这意味着最终它会占用更多 RAM,因为它没有被分页(呃,我不确定我自己是否明白 - 最好阅读博客!)
这是内存映射文件的 MSDN 文档,这是与 MMF 相关的另一个 SO 问题。
在这里查看我的答案;使用 VirtualUnlock() 您可以手动取消提交 MMF 的部分;例如,您认为不会很快再次访问的部分。