关于性能计数器

Windows 性能计数器提供一个高级抽象层,该层具有一个用于收集各种系统数据(例如处理器、内存和磁盘使用情况统计信息)的一致接口。 系统管理员使用性能计数器来监视性能或行为问题。 软件开发人员使用性能计数器来检查其组件的资源使用情况。

重要

Windows 性能计数器针对管理/诊断数据发现和收集进行了优化。 它们不适用于高频数据收集或应用程序分析,因为它们不是针对每秒进行多次收集而设计的。 为了降低访问系统信息的开销,你可能会更偏向于更直接的 API,例如 Process Status HelperGlobalMemoryStatusExGetSystemTimesGetProcessTimes。 对于分析,可以使用带有 -critsec-dpcisr-eflag-ProfileSource 选项的 tracelog.exe 来收集带有系统分析数据的 ETW 日志,或者也可以使用硬件计数器分析

注意

不要将 Windows 性能计数器与 QueryPerformanceCounter API 混淆。 Windows 性能计数器为多种系统信息提供高级抽象。 QueryPerformanceCounter 函数可实现对高精度时间戳的优化访问。

入门

概念

Windows 性能计数器系统分为使用者提供程序计数器集计数器实例计数器值

使用者是利用性能数据的软件组件。 Windows 包含多个使用性能数据的内置工具。 其中包括任务管理器、资源管理器、性能监视器、typeperf.exe、logman.exe 和 relog.exe。 开发人员可以编写通过性能计数器 API 访问性能计数器的脚本和应用程序。

提供程序生成和发布性能数据的软件组件。 提供程序将发布一个或多个计数器集的数据。 例如,数据库系统可能自行注册为性能数据提供程序。

  • V1 提供程序是一个软件组件,它通过在使用者进程中运行的性能 DLL 来发布性能数据。 V1 提供程序通过 .ini 文件安装到系统上。 V1 提供程序体系结构已弃用。 新提供程序应使用 V2 提供程序体系结构。
  • V2 提供程序 是一个软件组件,它通过性能计数器提供程序 API 来发布性能数据。 V2 提供程序通过 .man(XML 清单)文件安装到系统上。

计数器集是提供程序内的性能数据分组。 计数器集具有名称以及一个或多个计数器。 从计数器集收集数据会返回多个实例。 在某些 Windows API 中,计数器集被称为性能对象。 例如,数据库系统的性能数据提供程序可能会为每个数据库统计信息提供计数器集。

计数器是单个性能数据的定义。 计数器包含名称和类型。 例如,“每数据库统计信息”计数器集可能包含一个名为“每秒事务数”的计数器,其类型为 PERF_COUNTER_COUNTER

实例是报告性能数据的实体。 实例具有名称(字符串)以及一个或多个计数器值。 例如,“每数据库统计信息”计数器集可能为每个数据库包含一个实例。 实例名称将是数据库名称,每个实例将包含“每秒事务数”、“内存使用情况”和“磁盘使用情况”计数器的计数器值。

计数器值是单个性能计数器数据的值。 计数器值是一个无符号整数,可以是 32 位或 64 位,具体取决于相应计数器的类型。 在谈到实例时,计数器值有时可能称为计数器

提示

将性能计数器术语与更熟悉的电子表格术语相关联可能会有所帮助。 计数器集 类似于表。 计数器类似于列。 实例类似于行。 计数器值类似于表中的单元格。

单实例计数器集始终包含恰好一个实例的数据。 对于报告系统全局统计数据的计数器来说,这很常见。 例如,Windows 具有一个名为“Memory”的内置单实例计数器集,用于报告全局内存使用情况。

多实例计数器包含可变数量实例的数据。 对于报告系统中实体的计数器集来说,这很常见。 例如,Windows 具有一个名为“处理器信息”的内置多实例计数器集,用于为每个已安装 CPU 报告一个实例。

使用者将定期从提供程序的计数器集中收集和记录数据。 例如,使用者可能每秒或每分钟收集数据一次。 收集的数据称为示例。 示例包含时间戳以及计数器集实例的数据。 每个实例的数据包括实例名称(字符串)和一组计数器值(整数,计数器集中的每个计数器一个值)。

实例名称在示例中通常应是唯一的,即提供程序不应返回与单个示例一部分同名的两个实例。 某些较旧的提供程序不遵循此规则,因此使用者必须能够容忍非唯一实例名称。 实例名称不区分大小写,因此实例不应具有仅大小写存在差别的名称。

注意

出于向后兼容性的原因,“进程”计数器集将基于 EXE 文件名返回非唯一实例名称。 这可能会导致令人困惑的结果,特别是当具有非唯一名称的进程启动或关闭时,因为这通常会由于样本之间实例名称的不正确匹配而导致数据故障。 “进程”计数器的使用者必须能够容忍这些非唯一的实例名称以及由此产生的数据故障。 在 Windows 11 及更高版本中,可以使用 Process V2 计数器集来避免此问题。

实例名称在样本之间必须保持稳定,即每次收集计数器时,提供程序应为同一实体使用相同的实例名称。

每个计数器都有一个类型。 计数器类型指示计数器的原始值的类型(无符号 32 位整数或无符号 64 位整数)。 计数器类型还指示计数器的原始值表示的内容,这决定了应如何处理原始值以生成有用的统计信息。

尽管某些计数器类型很简单,并且具有直接有用的原始值,但许多计数器类型需要经过额外处理才能创建有用的格式化值。 为了生成格式化值,某些计数器类型需要来自两个样本的原始值,某些计数器类型需要时间戳,而某些计数器类型需要来自多个计数器的原始值。 例如:

  • PERF_COUNTER_LARGE_RAWCOUNT 是一个 64 位原始值,无需任何处理即可使用。 它适用于时间点值,例如“正在使用的内存字节数”。
  • PERF_COUNTER_RAWCOUNT_HEX 是一个 32 位原始值,只需要简单的十六进制格式即可使用。 它适用于时间点或标识信息,例如“标志”或“基地址”。
  • PERF_COUNTER_BULK_COUNT 是一个指示事件计数的 64 位原始值,并用于计算事件发生的速率。 为了发挥作用,此计数器类型需要两个存在时间间隔的样本。 格式化值是事件速率,即在两个样本之间的时间间隔内每秒发生事件的次数。 给定两个样本 s0s1,格式化值(事件率)将计算为 (s1.EventCount - s0.EventCount)/(s1.TimestampInSeconds - s0.TimestampInSeconds)

提供程序的行为应该类似于无状态,即从计数器收集数据不应明显影响提供程序的状态。 例如,当收集计数器集时,提供程序不应将计数器值重置为 0,也不应使用先前收集的时间戳来调整当前收集中的值。 相反,它应该提供具有准确类型的简单原始计数器值,以便使用者可以根据原始值及其时间戳计算有用的统计数据。

性能 API 体系结构

Performance counter applications invoke Windows APIs which call into providers to obtain performance data.

性能计数器使用者包括:

大多数性能计数器使用者使用 PDH.dll 中的 API 来收集性能数据。 PDH 管理收集性能计数器的许多复杂方面,例如解析查询、匹配多个样本中的实例以及从原始计数器数据计算格式化值。 PDH 实施在使用来自 V1 提供程序的数据时使用注册表 API,在使用来自 V2 提供程序的数据时使用 V2 使用者 API。

一些较旧的性能计数器使用者使用注册表 API 从特殊的 HKEY_PERFORMANCE_DATA 注册表项收集性能数据。 不建议对新代码执行此操作,因为注册表数据的处理非常复杂,而且容易出错。 注册表 API 实施直接支持从 V1 提供程序中收集数据。 它间接支持通过使用 V2 使用者 API 的转换层从 V2 提供程序收集数据。

一些性能计数器使用者使用 PerfLib V2 Consumer 函数直接访问来自 V2 提供程序的数据。 这比通过 PDH API 使用数据更复杂,但如果由于性能或依赖性问题而无法使用 PDH API,此方法可能会很有用。 PerfLib V2 实施直接支持从 V2 提供程序收集数据。 它不支持从 V1 提供程序收集数据。

注意

Windows OneCore 不包含 PDH.dll,也不支持通过注册表 API 使用性能计数器数据。 在 OneCore 上运行的使用者必须使用 PerfLib V2 Consumer 函数。

V1 提供程序作为加载到使用者进程中的提供程序 DLL 实施。 注册表 API 实施可管理加载提供程序 DLL、调用 DLL 以收集性能数据,并且可以根据需要卸载 DLL。 提供程序 DLL 负责收集适当的性能数据,例如,通过使用普通的 Windows API、RPC、命名管道、共享内存或其他进程间通信机制。

V2 提供程序被实现为用户模式程序(通常是 Windows 服务)或内核模式驱动程序。 通常,性能数据提供程序代码直接集成到现有组件中(即驱动程序或服务正在报告有关其自身的统计信息)。 PerfLib V2 实施通过 PCW.sys 内核扩展管理请求和响应,因此提供程序通常不需要实现任何进程间通信来提供性能数据。

注意

Windows 性能计数器 API 和工具包括对通过远程注册表(对于 V1 提供程序)和 RPC(对于 V2 提供程序)从其他计算机访问性能计数器的有限支持。 在身份验证控制(工具和 API 只能以当前用户身份进行身份验证)以及系统配置(默认情况下禁用必要的端点和服务)方面,这种支持不太适用。 在许多情况下,最好通过 WMI,而不是通过内置的远程访问支持来访问远程系统的性能计数器。

开发人员受众

管理员通常使用性能计数器来识别系统的性能问题或异常行为,开发人员通常使用性能计数器来研究软件组件的资源使用情况,个人用户通常使用性能计数器来了解程序在其系统上的行为方式。 可以通过任务管理器或性能监视器等 GUI 工具、typeperf.exe 或 logman.exe 等命令行工具,通过 WMI 和 PowerShell 编写脚本或通过 C/C++ 和 .NET API 进行使用。

性能计数器提供程序通常作为内核模式驱动程序或用户模式服务实施。 性能计数器提供程序通常以 C 或 C++ 编写。

运行时要求

有关特定编程元素运行时要求的信息,请参阅该元素参考页的“要求”部分。

有关版本历史记录,请参阅新增功能

另请参阅

使用性能计数器

性能计数器参考