【问题标题】:Memory-mapped files remain in physical memory?内存映射文件保留在物理内存中?
【发布时间】:2010-12-09 21:12:21
【问题描述】:

我有一个使用大量内存映射文件的进程。
问题是这些文件保存在物理内存中,即使机器内存不足,而其他进程也需要此内存。

我尝试使用SetProcessWorkingSetSize 来限制进程工作集,但没有帮助,进程的工作集不断增长超过最大值。

有没有更好的方法来限制进程的工作集?
我可以更改 Windows 的启发式方法来分页内存映射文件吗?

【问题讨论】:

    标签: windows memory-management memory-mapped-files


    【解决方案1】:

    我认为这种行为是由于 MMF(内存映射文件)的工作方式造成的。看看this 博客文章。它解释了 MMF 文件跳过 Windows 分页过程,因此不受页面文件的支持。相反,MMF 本身成为数据备份,这意味着最终它会占用更多 RAM,因为它没有被分页(呃,我不确定我自己是否明白 - 最好阅读博客!)

    Here's 内存映射文件的 MSDN 文档和here's 另一个与 MMF 相关的 SO 问题。

    【讨论】:

    • MSDN文章清楚地表明MMF API在VMM之上,所以它应该可以分页到磁盘并清除未使用的页面。
    【解决方案2】:

    如果您发现带有内存映射文件的进程占用了很多这些页面,那么这意味着操作系统不需要丢弃您的任何内存映射区域以提供给其他进程。那么,你怎么知道其他进程实际上需要当前用于映射文件的内存呢?仅仅因为操作系统的物理 RAM 不足就没有任何意义。其他进程必须要求内存才能使操作系统删除您的映射页面并为它们提供 RAM。

    因此,您的 mmap-I/O 进程似乎正在使您使用 RAM 频率较低的其他进程挨饿。一种方法是明智地将内存锁定在处于饥饿状态的进程中。查看用于 win32 的 VirtualLock。

    【讨论】:

    • 我知道是因为我也拥有另一个进程,我发现它有很多页面错误并且没有使用所需的内存。
    • 但是性能如何受到影响?当操作系统不必将脏页提交到磁盘时,页面错误可能非常便宜。如果您的其他进程使用的内存比您想象的要少,那么显然它实际上并不需要它。
    • 我应该提到它,(其他进程的)性能要慢几个数量级。
    • 好的,您的 I/O 访问模式导致虚拟内存管理器饿死您的其他进程。答案已编辑。
    • 在我启动另一个进程之前,mmf 进程已经有几分钟没有访问它的内存了,这仍然是饥饿的场景吗?
    【解决方案3】:

    查看我的答案here;使用 VirtualUnlock() 您可以手动取消提交 MMF 的部分;例如,您认为不会很快再次访问的部分。

    【讨论】:

      【解决方案4】:

      最终使用暴力破解 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);
              }
      }
      

      【讨论】:

      • 有趣。出于好奇,您在哪里执行此代码?
      • 每次访问映射文件时。
      猜你喜欢
      • 2014-03-04
      • 1970-01-01
      • 2011-02-18
      • 2017-11-16
      • 1970-01-01
      • 2011-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多