在 64 位 Windows Server 2003 上,我可以使用 taskmgr 或进程资源管理器看到总提交费用大约为 3.5GB,但是当我将每个进程消耗的私有字节数相加时(通过运行pslist -m
并添加列下的所有值Priv
),总数为 1.6GB。
我知道哪个进程似乎导致了这个问题(sqlservr.exe),因为当我终止该进程时,提交费用会大幅下降。然而,有问题的进程只消耗了约 220MB 的专用字节,而终止该进程会使提交费用下降约 1.6GB。
这怎么可能?提交费用怎么会比应该代表已提交内存量的私有字节数大得多呢?如果其他因素影响了提交费用,那么该因素是什么以及如何在流程资源管理器中查看其影响?
注意:我声称我已经了解了保留内存和已提交内存之间的区别:我上述的调查具体涉及私人字节仅包括坚定的内存并且不包括保留内存。在这种情况下,进程的虚拟大小超过 4GB,但这应该是无关紧要的 - procexp 中的虚拟大小代表保留的、未提交的内存,并且不应该计入提交费用。
我对这个问题的一般性答案特别感兴趣:我假设如果 sqlservr.exe 可以以这种方式运行,那么任何进程都可能如此。
进一步调查
我注意到将 Sysinternals VMMap 指向此进程会报告坚定的“私人的数据“1.6GB,尽管 Procexp 报告的专用字节数为 220MB。这尤其奇怪,因为“Windows® Sysinternals 管理员参考”中关于此字段的文档指出:
私有数据内存是由 VirtualAlloc 分配的内存,不会由堆管理器或 .NET 运行时进一步处理,也不会分配给堆栈类别...VMMap 对“私有数据”的定义比 Process Explorer 的“私有字节”更细致。Procexp 的“私有字节”包括属于该进程的所有私有提交的内存。
即 VMMap 提交的“私有数据”应该小于 procexp 的“私有字节”。
此外,在阅读了 Mark Russinovich 的优秀著作《进程提交的记忆》一书后,突破 Windows 的极限:虚拟内存他强调了两种不会出现在 Private Bytes 中的情况:
- 具有写时复制语义的文件映射视图(但是,根据 VMMap,没有为映射文件分配大量空间)。
- 页面文件支持的虚拟内存(但是,我
-l
按照建议尝试使用标志进行 testlimit,并且页面文件支持的部分不会消耗大量内存)
答案1
编辑:请注意,评论部分现在已不再相关,因为我的原始答案已经消失。
你的问题:
一个进程的私有字节数怎么会比它对系统提交费用的影响小得多呢?
这个问题可以用 Mark Russinovich 的一句话来回答:
有两种类型的进程虚拟内存计入提交限制:私有内存和页面文件支持内存。
归因于该进程的私有字节可能(并且通常是)小于该进程对系统提交费用的影响,因为该进程也可以分配页面文件支持的虚拟内存。
页面文件支持的虚拟内存很难归属于特定进程,因为它可以在进程之间共享。没有特定于进程的性能计数器可以告诉您任何进程已分配或正在引用多少页面文件支持的虚拟内存,但它仍然计入提交限制。
本文是关于这个主题的权威文章,在那篇文章中,他特别演示了一个进程已经分配了大量页面文件支持的VM,但该进程的私有字节仍然很低的情况。
他还向您展示了如何使用handle.exe
来检测节对象句柄的分配大小。这样您就可以检测出哪个进程对提交费用有如此大的影响。
您提到您已经查看过sqlservr.exe
并且handle.exe
它没有对大量部分对象开放的句柄,这些部分对象可以解释您杀死时释放的提交费用sqlservr.exe
。
巧合的是,内核空间中也有内存分配是根据系统提交限制收费的,例如分页池和非分页池,以及驱动程序锁定的内存,包括虚拟机气球驱动程序等。我不认为这与这个案例有关,但我不想不说出来。
SQL Server 是一个庞大而复杂的产品,由许多不同的进程组成,这些进程在系统上协同工作以提供所有 SQL Server 服务。事实上,SQL Server 有自己的内部内存管理器,从用于测量 Windows 虚拟内存分配的工具的角度来看,这让它看起来不太正常。
sqlservr.exe
并不是单独行动的。还有
msmdsrv.exe
(分析服务)sqlwriter.exe
(SQL VSS 编写器)sqlagent.exe
(SQL 代理)fdlauncher.exe
(全文过滤守护进程启动器)fdhost.exe
(全文主站)ReportingServicesService.exe
SQLBrowser.exe
当我杀死 时sqlservr.exe
,sqlagent.exe
也会自动死亡。这意味着系统提交费用将减少由 贡献的金额两个都进程。其他与 SQL 相关的进程也可能会在sqlservr.exe
被终止时释放页面文件支持的部分,即使这些进程本身仍在运行。所有这些都会导致 被终止时系统的当前提交费用下降sqlservr.exe
,即使它们从未成为 的私有字节的一部分sqlservr.exe
。