WinAPI 调用的目的VirtualLock
是将页面锁定到进程的工作集中。但是,WorkingSet64
API 莫名其妙地不计算这些页面。
可能因此,进程资源管理器和标准任务管理器都不会在其每个进程的内存使用统计信息中计算锁定页面。
这是怎么回事?非常熟悉 WinNT 中的虚拟内存的人能否解释一下这种不一致,这会导致千兆字节的已用 RAM 基本上未被检测到?(想想 SQL Server 或 VirtualBox)
WinAPI 调用的目的VirtualLock
是将页面锁定到进程的工作集中。但是,WorkingSet64
API 莫名其妙地不计算这些页面。
可能因此,进程资源管理器和标准任务管理器都不会在其每个进程的内存使用统计信息中计算锁定页面。
这是怎么回事?非常熟悉 WinNT 中的虚拟内存的人能否解释一下这种不一致,这会导致千兆字节的已用 RAM 基本上未被检测到?(想想 SQL Server 或 VirtualBox)
啊,这很容易解释:您使用了错误的 API。GetProcessWorkingSetSize 查询最小和最大工作集大小。这些是配额,而不是实际值。
最小工作集大小是 Windows 将保证在世界没有结束的情况下保持锁定在 RAM 中的大小。最大工作集大小是在页面移动到池中之前 Windows 允许您的进程的内存量(它们不一定会消失,但访问它们会导致错误和重新映射)。
编辑:
由于现在很清楚您没有使用错误的 API(只命名了错误的 func),因此我在我的 XP 系统上进行了一些测试(VirtualAlloc
和内存映射文件,两者都与 结合使用)。VirtualLock
乍一看,您似乎完全正确。从 650MB 文件中分配 512MB 或内存映射 512MB 会增加 512MB 到虚拟大小,但不会增加工作集。跟随 aVirtualLock(512MB)
根本不影响工作集!
然后我想到VirtualLock
在每种情况下都花费了零时间,这似乎不合理,例如必须从磁盘获取半 GB 的数据。所以,我检查了返回码并猜猜是什么。Windows 不认为锁定 512MB 是一个好主意,并且会拒绝这样做。
只用 64MB 重复实验,发现工作集立即增加了 64MB,正如它应有的那样。所以,一句话:“为我工作”。
可以肯定的是,您确实检查了返回码?
再看一遍,这种行为甚至是明确定义和有据可查的。VirtualLock
明确声明的文档:
一个进程可以锁定的最大页数等于它的最小工作集中的页数减去一个小的开销。
在适当设置 WS 配额后,无论是否锁定:
VirtualBox 是另一回事,你在任务管理器中看到的只是“接口”程序和“管理器”前端的工作集,两者始终保持在 64M 以下的工作集大小。虽然我不确定它可能会在某些驱动程序中分配什么内存,或者它们是否会锁定内存。
我目前正在运行 2 个虚拟机,每个虚拟机具有 1.6GB 主内存。看看我的 32 位 Windows 如何只看到 3.25GB,如果属于 VM 的内存被锁定,那将只剩下 50MB。此外,Process Explorer 告诉我,仅 Firefox 就有一个 474MB 的工作集,并且在我输入此内容时会增加(天啊...?!!)。这并不意味着虚拟机中的所有内存都被真正锁定,因为这样的数字在那时是完全不可能的。
根据要求,这是 VMMap 的截图:
这些数字确实很有趣……VM总共有160万,根据VMMap,821MiB被保留,772MiB被提交,Process Explorer只显示163MiB和54MiB,分别。那里肯定有些可疑,但我怀疑这可能是一些晦涩难懂的 VirtualBox 黑客,而不是 Windows 问题。