使用与调试器集成的 CPU 使用率 诊断工具,查找调试时的性能问题。 还可以在没有附加调试器的情况下或以正在运行的应用为目标来分析 CPU 使用情况。 有关详细信息,请参阅在发行版本或调试版本上运行分析工具和使用 CPU 分析对性能进行分析。
调试中断时,“诊断工具”窗口中的“CPU 使用率”工具收集有关应用程序中正在执行的函数的信息。 该工具将列出执行工作的函数,并提供时间线图,可专用于采样会话的特定部分。
重要事项
集成了调试器的诊断工具可用于 Visual Studio 中的 .NET 开发,包括 ASP.NET 和 ASP.NET Core,还可用于本机/C++ 开发。 需要相应的 Visual Studio 工作负载。 要运行带调试器的分析工具(“诊断工具”窗口),需具备 Windows 8 及更高版本。
在本教程中,你将:
- 收集 CPU 使用率数据
- 分析 CPU 使用率数据
步骤 1:收集 CPU 使用率数据
打开要在 Visual Studio 中调试的项目,并在应用中设置检查 CPU 使用率的断点。
在函数末尾或想要分析的代码区域中设置第二个断点。
通过设置两个断点,可将数据收集限制到想要分析的代码部分。
将自动显示“诊断工具”窗口,除非你已将其关闭。 若要再次显示该窗口,请依次单击“调试”>“Windows”>“显示诊断工具”。
可以使用工具栏上的“选择工具”设置,选择是否查看“CPU 使用率”、内存使用率或同时查看这两者。 如果运行的是 Visual Studio Enterprise,还可以在“工具”>“选项”>“IntelliTrace”中启用或禁用 IntelliTrace。
显示诊断工具的
显示诊断工具的
我们将主要查看 CPU 使用率,因此请确保已启用“CPU 使用率”(默认情况下已启用)。
依次单击“调试”>“启动调试”(或单击工具栏上的“启动”或按 F5)。
当应用完成加载后,将显示诊断工具的“摘要”视图。 如果需要打开窗口,请依次单击“调试”>“Windows”>“显示诊断工具”。
有关事件的详细信息,请参阅搜索和筛选“诊断工具”窗口中的“事件”选项卡。
运行会触发第一个断点的方案。
暂停调试器时,启用 CPU 使用情况数据收集,然后打开“CPU 使用情况” 选项卡。
选择 “记录 CPU 分析”时,Visual Studio 将开始记录您的函数及其执行所需的时间。 只能在应用程序在断点处停止时查看此收集的数据。
按 F5 将应用运行到第二个断点。
现在将拥有应用程序特定于在两个断点间运行的代码区域的性能数据。
探查器开始准备线程数据。 等待其完成。
CPU 使用率工具在“CPU 使用率”选项卡中显示报表。
如果想要选择要分析的更具体的代码区域,请在 CPU 时间轴中选择一个区域(它必须是显示分析数据的区域)。
现在可以开始分析数据。 如果在收集或显示数据时遇到问题,请参阅排查分析错误并修复问题。
提示
尝试确定性能问题时,需要获取多个度量值。 性能在运行间自然变化,并且由于加载 Dll、JIT 编译方法和初始化缓存等一次性的初始化工作,代码路径在首次运行时的执行速度通常较缓慢。 通过获取多个度量值,你可以更好地了解所显示指标的范围和中值,从而可比较首次与稳定状态下代码区域的性能。
步骤 2:分析 CPU 使用率数据
建议通过检查 CPU 使用率下的函数列表开始分析数据,然后确定执行大部分工作的函数,最后仔细查看每一个函数。
在函数列表中,检查执行大部分工作的函数。
提示
函数按照工作量从大到小的顺序列出(它们不是按照调用顺序)。 这有助于快速标识运行时间最长的函数。
在函数列表中,双击一个执行大量工作的应用函数。
双击该函数时,将在左侧窗格中打开“函数”视图。 从下拉菜单中选择“调用方/被调用方”视图。
在此视图中,所选函数显示在标题和“当前函数”框中(本例中为 DoWork)。 调用当前函数的函数显示在“调用函数”左下方,当前函数调用的任何函数均显示在右侧的“被调用函数”框中。 (可选择其中一个框来更改当前函数。)
此视图显示总时间及函数完成执行所用的总体应用运行时间的百分比。 “函数体”还显示函数体中所用的时间总量(及百分比),其中不包括调用和被调用函数中所用的时间。
双击该函数时,将在左侧窗格中打开“调用方/被调用方”视图。
在此视图中,所选函数显示在标题和“当前函数”框中(本例中为 GetNumber)。 调用当前函数的函数显示在“调用函数”左下方,当前函数调用的任何函数均显示在右侧的“被调用函数”框中。 (可选择其中一个框来更改当前函数。)
此视图显示总时间及函数完成执行所用的总体应用运行时间的百分比。 “函数体”还显示函数体中所用的时间总量(及百分比),其中不包括调用和被调用函数中所用的时间。 (在此示例中,共花费 2389 毫秒,函数体内花费 2367 毫秒,其余 22 毫秒花费在此函数调用的外部代码中)。
提示
“函数体”中的较高值可能指示函数自身内部的性能瓶颈。
若要按调用函数的顺序来查看较高级别的视图,请在顶部窗格的下拉列表中选择“调用关系树”。
图中每个带编号的区域都与过程中的一个步骤相关。
图像 描述 CPU 使用情况调用树中的顶级节点,表示应用程序。 在大多数应用中,当禁用“显示外部代码”选项时,二级节点是 [外部代码] 节点,该节点包含系统和框架代码,它可以启动和停止应用、绘制 UI、控制线程计划以及向应用提供其他低级服务。 二级节点的子级为用户代码方法和异步例程,它们由二级系统和框架代码进行调用或创建。 方法的子节点仅包含用于父方法调用的数据。 禁用“显示外部代码”后,应用方法只能包含 [外部代码] 节点。 下面是列值的详细信息:
总 CPU 表示由该函数及其调用的任何函数完成的工作量。 较高的总 CPU 值指向总体成本最高的函数。
自 CPU指示函数体中的代码完成的工作量,不包括由它调用的函数完成的工作。 较高的自 CPU 值可能指示函数自身内部的性能瓶颈。
“模块”包含函数的模块名或包含 [外部代码] 节点中的函数的模块数量。
要查看调用树视图中使用最高 CPU 百分比的函数调用,请单击“展开热路径”。 热路径有助于将调查重点放在影响最大的区域上。
备注
如果看到调用树中的代码标记为“已损坏”代码或“不可走堆栈”,则表示可能已删除 Windows事件跟踪 (ETW) 事件。 尝试第二次收集相同的跟踪以解决问题。
若要查看数据的其他视图,请从窗格顶部的下拉列表中选择“火焰图”。
火焰图提供了一种不同的调用树可视化形式,可帮助你进行数据分析。 有关详细信息,请参阅使用火焰图标识热路径。
若要查看函数或模块聚合的数据视图,请从窗格顶部的下拉列表中选择 函数 或 模块。
这些视图有助于识别由于高调用计数和/或性能问题的组合而可能成为性能瓶颈的函数或模块。
查看外部代码
外部代码是你编写的代码执行的系统和框架组件中的函数。 外部代码包含的部分函数,可启动和停止应用、绘制 UI、控制线程以及向应用提供其他低级别服务。 在大多数情况下,你不会对外部代码感兴趣,因此 CPU 使用率工具可将用户方法的外部函数收集到一个 [外部调用] 节点中。
如果要查看外部代码的调用路径,请从“设置”列表中取消选择“仅显示我的代码”,然后选择“应用”。
外部代码是你编写的代码执行的系统和框架组件中的函数。 外部代码包含的部分函数,可启动和停止应用、绘制 UI、控制线程以及向应用提供其他低级别服务。 在大多数情况下,你不会对外部代码感兴趣,因此 CPU 使用率工具可将用户方法的外部函数收集到一个 [外部代码] 节点中。
若要查看外部代码的调用路径,请从“筛选器视图”列表中选择“显示外部代码”,然后选择“应用”。
请注意,许多外部代码调用链已深度嵌套,因此函数名列的宽度可能超过所有计算机监视器(最大的计算机监视器除外)的显示宽度。 发生这种情况时,函数名将显示为 […]。
使用搜索框找到要查找的节点,然后滑动水平滚动条将数据带入视图中。
提示
如果分析调用 Windows 函数的外部代码,应确保具有最新的 .pdb 文件。 如果没有这些文件,您的报表视图将列出晦涩难懂的 Windows 函数名称。 有关如何确保具有所需文件的详细信息,请参阅在调试器中指定符号 (.pdb) 和源文件。
后续步骤
本教程中介绍了如何收集和分析 CPU 使用量数据。 如果已经完成了探查器简介,你可能还想通过一个教程来学习如何更有效地使用这些工具。
在本教程中,你了解了如何在调试时收集和分析 CPU 使用情况数据。 你可能想要详细了解如何使用性能分析器分析发布版本。