通过分析 CPU 使用率来衡量应用程序性能(C#、Visual Basic、C++、F#)

使用与调试器集成的 CPU 使用率 诊断工具,查找调试时的性能问题。 还可以在不附加调试器的情况下或通过面向正在运行的应用来分析 CPU 使用率。 有关详细信息,请参阅在发行版本或调试版本上运行分析工具使用 CPU 分析对性能进行分析

当调试器暂停时,诊断工具窗口中 CPU 使用率 工具收集有关应用程序中正在执行的函数的信息。 该工具列出了正在执行工作的函数,并提供可用于专注于采样会话的特定段的时间线图。

重要

集成了调试器的诊断工具可用于 Visual Studio 中的 .NET 开发,包括 ASP.NET 和 ASP.NET Core,还可用于本机/C++ 开发。 需要相应的 Visual Studio 工作负载。 Windows 8 及更高版本需要使用调试器运行分析工具(诊断工具 窗口)。

在本教程中,你将:

  • 收集 CPU 利用率数据
  • 分析 CPU 使用率数据

步骤 1:收集 CPU 利用率数据

  1. 打开要在 Visual Studio 中调试的项目,并在要检查 CPU 使用情况的点在应用中设置断点。

  2. 在要分析的函数或代码区域的末尾设置第二个断点。

    通过设置两个断点,可以将数据收集限制为要分析的代码部分。

  3. 诊断工具 窗口将自动显示,除非你已将其关闭。 若要再次显示该窗口,请依次单击“调试”>“Windows”>“显示诊断工具”

  4. 可以选择是查看 CPU 使用率内存使用率,还是同时查看工具栏上的 选择工具 设置。 如果运行的是 Visual Studio Enterprise,还可以在 Tools>Options>IntelliTrace中启用或禁用 IntelliTrace。

    显示诊断工具的 屏幕截图。

    显示诊断工具的 屏幕截图。

    我们将主要查看 CPU 利用率,因此请确保启用 CPU 使用率(默认启用)。

  5. 单击 调试>启动调试(或工具栏上的 启动,或 F5)。

    应用完成加载后,将显示诊断工具的“摘要”视图。 如果需要打开窗口,请依次单击“调试”>“Windows”>“显示诊断工具”

    显示“诊断工具摘要”选项卡的屏幕截图。

    显示“诊断工具摘要”选项卡的屏幕截图。

    有关事件的详细信息,请参阅 “搜索和筛选诊断工具”窗口的“事件”选项卡。

  6. 运行会触发第一个断点的方案。

  7. 暂停调试器时,启用 CPU 使用情况数据收集,然后打开“CPU 使用情况” 选项卡。

    显示诊断工具启用 CPU 分析的屏幕截图。

    显示诊断工具启用 CPU 分析的屏幕截图。

    选择 “记录 CPU 分析”时,Visual Studio 将开始记录您的函数及其执行所需的时间。 只能在应用程序在断点处停止时查看此收集的数据。

  8. 按 F5 将应用运行到第二个断点。

    现在,你已经为应用程序提供了性能数据,具体适用于两个断点之间运行的代码区域。

    探查器开始准备线程数据。 等待其完成。

    显示诊断工具准备线程的屏幕截图。

    显示诊断工具准备线程的屏幕截图。

    CPU 使用率工具在“CPU 使用率” 选项卡中显示报表。

    显示“诊断工具 CPU 使用率”选项卡的屏幕截图。

    显示“诊断工具 CPU 使用率”选项卡的屏幕截图。

  9. 如果要选择要分析的更具体的代码区域,请在 CPU 时间线中选择一个区域(必须是显示分析数据的区域)。

    显示诊断工具选择时间段的屏幕截图。

    显示诊断工具选择时间段的屏幕截图。

    此时,可以开始分析数据。 如果在收集或显示数据时遇到问题,请参阅 排查分析错误并修复的问题。

    提示

    尝试识别性能问题时,请进行多次度量。 由于加载 DLL、JIT 编译方法和初始化缓存等一次性初始化工作,性能自然会有所不同,代码路径通常在首次运行时执行速度变慢。 通过采用多个度量值,可以更好地了解所显示的指标的范围和中值,这允许你第一次比较代码区域的稳定状态性能。

步骤 2:分析 CPU 使用率数据

建议先检查 CPU 使用率下的函数列表,确定正在执行最大工作的函数,然后仔细查看每个函数,从而开始分析数据。

  1. 在函数列表中,检查正在执行最大工作的函数。

    显示诊断工具 CPU 使用率函数列表的屏幕截图。

    显示诊断工具 CPU 使用率函数列表的屏幕截图。

    提示

    函数按照工作量从大到小的顺序列出(它们不是按照调用顺序)。 这有助于快速识别运行时间最长的函数。

  2. 在函数列表中,双击正在执行大量工作的应用函数之一。

    双击函数时,函数 视图将在左窗格中打开。 从下拉菜单中选择“调用方/被调用方”视图

    显示诊断工具 Caller Callee 视图的屏幕截图。

    在此视图中,所选函数显示在标题和 当前函数 框中(在本示例中为 DoWork)。 调用当前函数的函数显示在 调用函数的左侧,当前函数调用的任何函数显示在右侧 调用的函数 框中。 (可以选择任一框来更改当前函数。

    此视图显示函数完成的总时间(ms)和整个应用运行时间的百分比。 函数体还显示函数体中所用的时间总量(及百分比),其中不包括调用和被调用函数中所用的时间。

    双击该函数时,将在左侧窗格中打开“调用方/被调用方”视图。

    显示诊断工具“调用方/被调用方”视图的屏幕截图。

    在此视图中,所选函数显示在标题和 当前函数 框中(本示例中的 GetNumber)。 调用当前函数的函数显示在 调用函数的左侧,当前函数调用的任何函数显示在右侧 调用的函数 框中。 (可以选择任一框来更改当前函数。

    此视图显示函数完成的总时间(ms)和整个应用运行时间的百分比。 函数体还显示函数体中所用的时间总量(及百分比),其中不包括调用和被调用函数中所用的时间。 (在此示例中,函数体中花费了 2389 毫秒中的 2367 毫秒,其余 22 毫秒用于此函数调用的外部代码中)。

    提示

    函数主体 中的高值可能表示函数本身的性能瓶颈。

  3. 若要查看显示调用函数的顺序的更高级别视图,请从窗格顶部的下拉列表中选择 调用树

    该图中的每个编号区域都与过程中的步骤相关。

    诊断工具调用树

    图像 描述
    步骤 1 CPU 使用情况调用树中的顶级节点,表示应用程序。
    步骤 2 在大多数应用中,当禁用 显示外部代码 选项时,第二级节点是一个 [外部代码] 节点,其中包含启动和停止应用的系统和框架代码、绘制 UI、控制线程计划,并向应用提供其他低级别服务。
    步骤 3 第二级节点的子级是二级系统和框架代码调用或创建的用户代码方法和异步例程。
    步骤 4 方法的子节点仅包含父方法调用的数据。 禁用 显示外部代码 时,应用方法还可以包含 [外部代码] 节点。

    下面是列值的详细信息:

    • 总 CPU 表示由该函数及其调用的任何函数完成的工作量。 较高的总 CPU 值指向总体成本最高的函数。

    • 自 CPU指示函数体中的代码完成的工作量,不包括由它调用的函数完成的工作。 较高的自 CPU 值可能指示函数自身内部的性能瓶颈

    • 模块 包含函数的模块的名称,或包含 [外部代码] 节点中函数的模块数。

    要查看调用树视图中使用最高 CPU 百分比的函数调用,请单击“展开热路径”。 热路径有助于将调查重点放在影响最大的区域上。

    显示诊断工具热路径的屏幕截图。

    备注

    如果看到调用树中的代码标记为“已损坏”代码或“不可走堆栈”,则表示可能已删除 Windows 事件跟踪 (ETW) 事件。 尝试第二次收集相同的跟踪以解决问题。

  4. 若要查看数据的不同视图,请从窗格顶部的下拉列表中选择 火焰图

    火焰图提供了一种不同的调用树可视化形式,可帮助你进行数据分析。 有关详细信息,请参阅 使用火焰图标识热路径。

查看外部代码

外部代码是由你编写的代码执行的系统和框架组件中的函数。 外部代码包括启动和停止应用的函数、绘制 UI、控制线程以及向应用提供其他低级别服务。 在大多数情况下,你不会对外部代码感兴趣,因此 CPU 使用率工具将用户方法的外部函数收集到一个 [外部调用] 节点中。

如果要查看外部代码的调用路径,请从 设置 列表中选择 “仅显示我的代码”,然后选择 “应用”

显示“设置”中“仅显示我的代码”的屏幕截图。

外部代码是由你编写的代码执行的系统和框架组件中的函数。 外部代码包括启动和停止应用的函数、绘制 UI、控制线程以及向应用提供其他低级别服务。 在大多数情况下,你不会对外部代码感兴趣,因此 CPU 使用情况工具将用户方法的外部函数收集到一个 [外部代码] 节点中。

如果要查看外部代码的调用路径,请从 筛选器视图 列表中选择 显示外部代码,然后选择 应用

显示“选择筛选器视图”的屏幕截图,然后显示外部代码。

请注意,许多外部代码调用链是深度嵌套的,因此函数名称列的宽度可以超过所有计算机监视器的显示宽度。 发生这种情况时,函数名称显示为

使用搜索框查找要查找的节点,然后使用水平滚动条将数据引入视图。

提示

如果分析调用 Windows 函数的外部代码,应确保具有最新的 .pdb 文件。 如果没有这些文件,您的报表视图将列出晦涩难懂的 Windows 函数名称。 有关如何确保具有所需文件的详细信息,请参阅在调试器中指定符号 (.pdb) 和源文件

后续步骤

本教程介绍了如何收集和分析 CPU 使用情况数据。 如果已经完成了探查器简介,你可能还想通过一个教程来学习如何更有效地使用这些工具。

在本教程中,你已了解如何在调试时收集和分析 CPU 使用率数据。 你可能想要详细了解如何使用性能分析器分析发布版本。