为什么锁定的页面不计入工作集大小?

时间:2011-04-13 12:24:46

标签: windows winapi paging virtual-memory

VirtualLock WinAPI调用的目的是将页面锁定到进程的工作集中。但是,WorkingSet64 API莫名其妙地不计算这些页面。

可能因此,neither Process Explorer或标准Task Manager计算了每进程内存使用情况统计信息中的锁定页面。

这是怎么回事?是否有人非常熟悉WinNT中的虚拟内存,可以解释这种不一致性,这可能会导致千兆字节的已用RAM基本上未被发现? (想想SQL Server或VirtualBox)

1 个答案:

答案 0 :(得分:3)

啊,这很容易解释:你使用的是错误的API。 GetProcessWorkingSetSize查询最小和最大工作集大小。这些是配额,而不是实际值。

只要世界没有结束,Windows将保证锁定在RAM中的最小工作集大小。最大工作集大小是Windows在页面移入池之前允许进程的内存量(它们不一定会消失,但访问它们会导致错误并重新映射)。

您想要GetProcessMemoryInfo

修改
既然现在很清楚你没有使用错误的API(只是命名错误的func),我已经完成了一些测试(VirtualAlloc和内存映射文件,两者都与VirtualLock结合使用) XP系统。乍一看,看起来你是完全正确的。从650MB文件中分配512MB或内存映射512MB,为虚拟大小增加了512MB,但没有增加工作集。使用VirtualLock(512MB)后,根本不会影响工作集!

然后我突然意识到VirtualLock在每种情况下都花费了零时间,这似乎不合理,例如因为必须从磁盘获取半千兆字节。所以,我检查了返回代码并猜测是什么。 Windows并不认为锁定512MB是一个好主意,并且会拒绝这样做。

重复实验只有64MB,不料,工作集立即上升了64MB,就像它应该的那样。所以,总之一句:“为我工作”。

为了确定,您确实检查了返回代码?

再看一下,这种行为甚至是定义明确且记录良好的。明确指出VirtualLock的文档:

  

a的最大页数   进程可以锁定等于   最低工作量的页数   设置减去一小部分开销。

在适当设置WS配额后,有和没有锁定:

VirtualBox是另一回事,您在任务管理器中看到的只是“接口”程序和“管理器”前端的工作集,两者都始终保持工作集大小低于64M。虽然我不确定它可能在某些驱动程序中分配了什么内存,或者它们是否锁定了内存。

我目前正在运行2台虚拟机,每台主机内存为1.6GB。看看我的32位Windows如何只看到3.25GB,如果属于VM的内存被锁定,那将只留下50MB。此外,Process Explorer告诉我,单独的Firefox有一个474MB的工作集,当我打字时它正在上升(神圣......?!!)。这并不会使虚拟机中的所有内存都被锁定,因为这样的数据完全是不可能的。

根据要求,这里是VMMap的一个镜头: enter image description here

这些数字无疑是有趣的......根据VMMap 821MiB保留的VM总数为1.6M,提交了772MiB,Process Explorer仅分别显示163MiB和54MiB。那里肯定有些东西可疑,但我怀疑这可能是一些不起眼的VirtualBox hackery而不是Windows问题。