在过去的几天里我学到了有关 WMI 和性能计数器的所有知识。
WMI 代表 Windows 管理规范。 WMI 是向 WMI 系统和 Windows COM 子系统注册的类的集合。这些类称为提供程序,并且具有任意数量的公共属性,这些属性在查询时返回动态数据。
Windows 预装了大量 WMI 提供程序,可为您提供有关 Windows 环境的信息。对于这个问题我们关心的是Win32_PerfRawData* 提供程序 http://msdn.microsoft.com/en-us/library/windows/desktop/aa394084%28v=vs.85%29.aspx以及基于它构建的两个包装器。
如果您直接查询任何 Win32_PerfRawData* 提供程序,您会发现它返回的数字看起来很可怕。这是因为这些提供商提供了原始数据,您可以使用它们来计算您想要的任何内容。
为了更轻松地使用 Win32_PerfRawData* 提供程序,Microsoft 提供了两个包装器,它们在查询时返回更好的答案:PerfMon 和 Win32_PerfFormattedData* 提供程序。
好的,那么我们如何获取进程的 CPU 利用率百分比呢?我们有三个选择:
- 从 Win32_PerfFormattedData_PerfProc_Process 提供程序获取格式良好的数字
- 从 PerfMon 获取格式良好的数字
- 使用 Win32_PerfRawData_PerfProc_Process 计算我们自己的 CPU 利用率百分比
我们将看到选项 1 存在一个错误,因此它并不在所有情况下都有效,尽管这是互联网上通常给出的答案。
如果您想从 Win32_PerfFormattedData_PerfProc_Process 获取此值,您可以使用问题中提到的查询。这将为您提供该进程的所有线程的 PercentProcessorTime 值的总和。问题是,如果有超过 1 个核心,则该总和可能 >100,但该属性的最大值为 100。因此,只要该进程的所有线程的总和小于 100,您就可以通过除以该进程的线程数来得到答案PercentProcessorTime 属性由机器的核心数决定。
如果您想从 PowerShell 中的 PerfMon 获取此值,您可以使用Get-Counter "\Process(SqlServr)\% Processor Time"
。这将返回 0 - (CoreCount * 100) 之间的数字。
如果您想自己计算该值,Win32_PerfRawData_PerfProc_Process 提供程序上的 PercentProcessorTime 属性将返回该进程已使用的 CPU 时间。因此,您需要拍摄两个快照,我们将它们称为 s1 和 s2。然后我们将执行 (s2.PercentProcessorTime - s1.PercentProcessorTime) / (s2.TimeStamp_Sys100NS - s1.TimeStamp_Sys100NS)。
这就是最终的结论。希望对您有帮助。