方案指南:排查 WMI 性能问题

本文介绍了检查内存泄漏或处理泄漏的不同方法,以解决 Windows Management Instrumentation (WMI) 性能问题,以及如何收集其他信息。

可能会遇到以下情况或问题:

  • 计算机运行缓慢。
  • 运行命令(如 tasklist 或打开 msinfo32.execompmgmt.msc )需要很长时间才能响应或未显示适当的结果。
  • 应用程序或客户端(具体取决于 WMI)在提取或显示信息时出现问题,或者最终失败。
  • WMI 查询失败,出现WBEM_E_INVALID_CLASS或WBEM_E_NOT_FOUND等错误。
  • WMI 服务 (Winmgmt) 未响应。
  • 计算机的总内存达到 100%。

你还注意到, svchost.exe (托管 Winmgmt 服务)或其中一个 WmiPrvse.exe 进程消耗了高内存或在任何给定时间在任务管理器中具有较高的句柄计数。 如果重启计算机或 Winmgmt 服务或手动终止有问题的 WmiPrvse.exe 进程,则会暂时缓解高内存情况。 但是,此问题在一段时间后再次出现。

内存泄漏或处理泄漏的可能原因

如果 WMI 服务或 WmiPrvse.exe 进程消耗内存或句柄,并且不会随时间推移减少或释放句柄,则分别被视为内存泄漏或处理泄漏。

泄漏的原因因方案而异,但通常由以下原因引起:

  • 应用程序或服务发出的有问题、效率低下或巨大的 WMI 查询。
  • 查询频率高。
  • 非Microsoft产品的干扰。
  • 与要查询的 WMI 类关联的对象。

尽管调查内存或处理泄漏需要深入分析 WMI 服务或 WmiPrvse.exe 进程的查询和调试转储,但初始故障排除步骤可以帮助缩小范围或解决问题。

下面是执行 WMI 查询的生命周期:

  1. 客户端提交查询。
  2. WMI 服务将查询存储为其内存中名为“缓冲缓冲区内存”的任务。
  3. WMI 服务调用相应的 WMI 提供程序来执行查询。
  4. WMI 提供程序将查询结果返回到 WMI 服务,并将结果存储在缓冲缓冲区中。
  5. 客户端检索查询结果。
  6. 查询和结果将从缓冲器中解除分配。

如果发生 WMI 服务内存或句柄泄漏,则缓冲缓冲区可能会填充过多的任务或查询结果,为其他查询留无更多空间。

  • 如果使用的是早于 Windows Server 2016 的操作系统(OS)版本,WMI 服务将与其他服务一起在共享 svchost.exe 容器下运行。
  • 如果svchost.exe容器泄漏内存或句柄,则需要首先确定此泄漏是由 WMI 服务或svchost.exe容器中的任何其他服务引起的。

若要确定这一点,请执行以下步骤:

  1. 使用SC Config WINMGMT Type= Own命令将 WMI 服务隔离到其自己的svchost.exe容器。
  2. 重启 Winmgmt 服务。
  3. tasklist /svc 命令将显示每个 svchost.exe 容器下托管的所有正在运行的进程和服务的列表。 如果命令正常工作,应会看到 Winmgmt 服务在单独的独立 svchost.exe 容器下运行。
  4. 继续监视其内存或处理使用情况。 如果它随着时间的推移继续增加,并且根本不会减少,则意味着 Winmgmt 服务是一个泄漏的内存或句柄。 如果没有,你可能会看到另一个 svchost.exe 容器托管其他服务泄漏内存或句柄。
  5. 若要还原更改,请运行 SC Config WINMGMT Type= Share 命令。

泄漏通常是由于客户端行为有问题或连接问题导致的,这可以防止与查询相关的任务对象正确释放。

若要确定是否涉及有问题的客户端,需要了解泄漏的模式并查看任务管理器,以查看内存在特定时间或任何应用程序的特定操作期间是否增加。 例如,只要安装了 Windows 更新,WMI 服务内存消耗就会增加。

若要使用 性能监视器(Perfmon)监视任何进程的内存使用情况或处理计数(WMI 服务或WmiPrvse.exe进程),请执行以下步骤:

  1. 请注意包含 Winmgmt 服务或WmiPrvse.exe进程(泄漏内存或句柄)的svchost.exe的进程 ID(PID)。

  2. “运行”窗口中输入 Perfmon 以打开性能监视器。

  3. 在左窗格中选择性能监视器,然后在右侧窗格中选择加号(+),打开“添加计数器”窗口。

  4. 展开 “进程 ”并选择“ ID 进程”。 选择所有 WmiPrvse#svchost# 实例,然后选择“添加>确定”。

    显示已选择所有 WmiPrvse# 实例和 svchost# 实例的屏幕截图。

  5. 对于列表中的每个项,你将看到“最后”、“平均值”和“最小值”具有相同的值,即该过程的 PID。

    显示具有相同“最后”、“平均值”和“最小值”的项是进程的 PID 的屏幕截图。

  6. 浏览列表中的所有项,找到 Winmgmt 服务或 WmiPrvse.exe 进程(泄漏内存或句柄)的 PID。 然后,记下确切 的 svchost#WmiPrvse# 实例。

  7. 从列表中删除所有项。

  8. 再次选择“添加计数器”,然后在“进程”下,选择“句柄计数”、“专用字节数”、“线程计数”和“工作集”。

  9. 选择正确的 svchost#WmiPrvse# 实例,然后选择“ 添加”。 这将显示所选进程消耗的资源的图形表示形式。

    “添加计数器”窗口的屏幕截图,其中选择了 WmiPrvse# 实例。

  10. 如果内存或句柄计数在特定时间间隔或一天的特定时间或任何操作时增加,则结束。 了解泄漏模式后, 在内存或句柄增加时分析传入的查询

  11. 查找任务上存在巨大、频繁或长时间的查询。

    注意

    查看传入的查询是确定一个或多个可能正在执行有问题的查询或异常的客户端进程。

  12. 拥有可疑客户端后,可以通过暂时卸载或禁用它,然后重启 WMI 服务来测试它。

如果未发生内存泄漏,则标识的客户端进程是问题的原因。

存储库膨胀

查看存储在 C:\Windows\System32\wbem\Repository 下的 WMI 存储库的大小。 了解或确定存储库的大小:

  • 存储库的大小取决于多种因素,例如计算机上的资源和负载、计算机上安装的活动服务和应用程序以及环境(例如,它是否属于群集或 SQL Server)。
  • 对于服务器 OS,正常的存储库大小可能为几百 MB 到 1.5 GB。 对于客户端 OS,大小可以是几百 MB。 存储库不一定保持特定大小,并且没有写入的限制。
  • 仅当计算机遇到本文开头所述的问题或症状时,才会被视为可疑大小(超过 1 GB)。
  • 存储库大小异常大或随着时间的推移而增长。 在这种情况下,存储库可能会膨胀。

必须使用专用工具检查膨胀的存储库,以确定其确切原因。 可以打开捕获数据的Microsoft支持案例

但是,在大多数情况下,膨胀的 WMI 存储库是由策略结果集(RSoP)日志记录或监视应用程序(如 Microsoft System Center Configuration Manager(SCCM)引起的。

有关 RSoP 日志记录问题,请参阅 Windows 或 Windows Server 中大型 WMI 存储库导致的意外登录速度缓慢。

即使在应用解决方案后,仍必须重置 WMI 存储库以减小其大小。 不建议在Microsoft支持专业人员之前的指导的情况下重置 WMI 存储库。

如果上述步骤无法解决问题,则需要收集跟踪和转储并将其发送给Microsoft支持专业人员进行更深入的调查,如“数据收集”部分所述

WmiPrvse.exe进程正在泄漏句柄或内存

如果WmiPrvse.exe进程正在泄漏句柄或内存,则可能是下列情况之一:

  • 客户端应用程序执行异常、低效或大型查询。
  • WmiPrvse.exe进程在处理 WMI 查询时不会按预期释放资源,这会导致内存泄漏并停止WmiPrvse.exe进程。
  • 计算机或环境设置的规模很大。

有关这些情况,请参阅“方案指南:排查WmiPrvse.exe配额超出问题或方案的问题”。

数据收集

若要提出进一步调查的支持案例,可以按照 使用 TSS 收集用户体验问题 的信息或使用最近遇到的问题的计算机上的 WMI-Collect 工具收集信息来收集信息。 步骤如下:

  1. 下载WMI-Collect.zip并将其解压缩到 C:\temp文件夹。

  2. 在提升的 PowerShell 命令提示符下,从保存脚本的文件夹运行 WMI-Collect.ps1 脚本。 例如:

    C:\temp\WMI-Collect.ps1 -Logs
    
  3. 使用“按 Enter 停止捕获:”消息,使 PowerShell 命令提示符保持打开状态。

  4. 该脚本创建一个子文件夹,其中包含所有跟踪的结果和诊断信息。 压缩文件夹。 创建支持案例后,可以将此文件上传到安全工作区进行分析。