使用 .NET 对象分配工具分析内存使用情况

可以使用 .NET 对象分配工具查看应用使用的内存量以及代码路径分配的最大内存量。

运行该工具后,可以看到正在分配对象的函数执行路径。 然后,可以追溯到占用最多内存的调用树的根。

有关如何使用 .NET 对象分配工具提高性能的教程,请参阅 案例研究:优化代码初学者指南。

设置

  1. 在 Visual Studio 项目中,将解决方案配置设置为 Release 并选择部署目标。

    部署目标通常与项目名称匹配,表示本地部署。

  1. 选择 “调试>性能探查器 ”以在 Visual Studio 中打开性能探查器。

  2. “独立 ”选项卡上,选中 “.NET 对象分配跟踪” 复选框。

    显示选中“.NET 对象分配跟踪”复选框的屏幕截图。

  1. 选择 Alt+F2 以在 Visual Studio 中打开性能探查器。

  2. 选中 .NET 对象分配跟踪 复选框。

    所选 Dotnet 对象分配跟踪工具的屏幕截图。

  1. 选择 “开始”按钮以运行该工具。

    如果在启动探查器之前启用了“在暂停后开始收集”选项,则在诊断会话视图中选择“记录”按钮之前,不会收集数据

  2. 在此工具开始运行后,在应用中完成要探查的方案。 然后选择 停止收集 或关闭应用以查看数据。

    显示“停止收集”窗口的屏幕截图。

  3. 选择 分配 选项卡。将显示类似于以下内容的内存分配数据。

    “分配”选项卡的屏幕截图。

现在可以分析对象的内存分配。

在收集过程中,跟踪工具可能会减慢被探查的应用的速度。 如果跟踪工具或应用的性能缓慢,并且不需要跟踪每个对象,则可以调整采样率。 为此,请在探查器摘要页中选择跟踪工具旁边的齿轮符号。

显示 .NET 对象分配跟踪的设置按钮的屏幕截图。

Dotnet 分配工具的设置的屏幕截图。

将采样率调整为所需的速率。 此更改有助于在收集和分析期间加快应用的性能。

调整采样率的屏幕截图。

有关如何提高工具效率的详细信息,请参阅 优化探查器设置

了解数据

在以下图形视图中,顶部图形显示应用中的实时对象数。 最下面的“对象增量”图显示了应用对象数变化率 (%)。 红色条表示垃圾回收何时发生。

DotNet 分配工具图表的屏幕截图。

可以通过选择时间范围来筛选表格数据,以便仅显示指定时间范围的活动。 执行此操作时,选项卡中显示的信息的范围限定为筛选的时间范围。

Dotnet 分配时间的筛选图的屏幕截图。

还可以放大或缩小图形。

洞见

如果见解视图显示任何见解,请使用提供的链接获取有关所标识问题的详细信息。

获取 AI 帮助

如果你有 Copilot,则可以在查看顶级见解时获得 AI 帮助。 Copilot 提供与一组特定性能见解相关的信息和见解。 借助 Copilot,您还可以询问关于占用内存最多的对象的问题,这有助于编写更高效或更经济的代码。

即使没有确定具体的性能见解,也会出现 Copilot 按钮 “Copilot”按钮的屏幕截图。。 选择 Copilot 按钮,从 Copilot 中学习并开始提问。

获取 AI 帮助

如果你有 Copilot,则可以在查看顶级见解时获得 AI 帮助。 Copilot 提供与一组特定性能见解相关的信息和见解。 借助 Copilot,您还可以查询哪些对象使用了最多的内存,这有助于生成更高效或更具成本效益的代码。

即使没有确定具体的性能见解,也会出现询问 Copilot 按钮 “询问 Copilot”按钮的屏幕截图。。 选择“询问 Copilot”,以便从 Copilot 学习并开始提问。

分配

分配 视图显示分配内存的对象的位置以及这些对象分配的内存量。

已展开的分配视图屏幕截图。

以下信息显示在 分配 视图中:

  • 类型 列是占用内存的类和结构的列表。 双击某一类型,以倒调用树的形式查看其回溯。 仅在 分配 视图中,可查看选定类别中占用内存的项目。

  • 分配 列显示在特定分配类型或函数中占用内存的对象数。 此列仅显示在 分配调用树函数 视图中。

  • 默认情况下,字节平均大小(字节)列不显示。 若要显示它们,请右键单击 类型分配 列,然后选择 字节平均大小(字节) 选项将其添加到图表。

    这两列类似于 总计(分配)自(分配),但它们显示占用的内存量,而不是占用内存的对象数。 这些列仅显示在 分配 视图中。

  • 模块名称 列显示包含正在调用的函数或进程的模块。

所有这些列都是可排序的。 对于 类型模块名称 列,可以按字母顺序按升序或降序对项进行排序。 对于 分配字节平均大小(字节),您可以按数值升序或降序对项目进行排序。

符号

以下符号显示在 分配调用树函数 选项卡中:

  • 值类型符号 - 值类型(如整数)

  • 值类型集合符号 - 值类型集合,如整数数组

  • 引用类型符号 - 引用类型,如字符串

  • 引用类型集合符号 - 引用类型集合,如字符串数组

调用树

调用树 视图显示包含分配大量内存的对象的函数执行路径。

“调用树”视图的屏幕截图。

以下信息显示在 调用树 视图中:

  • 函数名称 列显示包含分配内存的对象的函数的进程或名称。 显示基于正在检查的节点级别。
  • 总计(分配)总大小(字节)列显示了已分配的对象数,以及函数及其调用的其他所有函数使用的内存量。 默认情况下,总大小(字节) 列处于隐藏状态。
  • “自身(分配)”和“自大小(字节)”列显示了已分配的对象数,以及所选的一个函数或分配类型使用的内存量。
  • 平均大小(字节) 列显示的信息与 分配 视图中的信息相同。 默认情况下,此列处于隐藏状态。
  • 模块名称 列显示包含正在调用的函数或进程的模块。

调用树”视图中显示的其他选项包括:

  • “展开热路径”按钮突出显示了包含许多正在分配内存的对象的函数执行路径。 该算法从你选择的节点开始,并突出显示大多数分配的路径,指导你进行调查。
  • 显示热路径 按钮显示或隐藏指示哪些节点是热路径的一部分的火焰符号。

展开的热路径的屏幕截图。

Functions

Functions 视图显示分配内存的进程、模块和函数。

函数视图的屏幕截图。

函数”视图中显示的信息包括:

  • “名称”列将进程显示为最高级别的节点。 进程下方是模块,模块下方是函数。

  • 以下列中显示的信息与“分配”和“调用树”视图中显示的信息相同:

    • 总计(分配)
    • 自身(分配)
    • 总大小(字节)
    • 自大小(字节)
    • 平均大小(字节)

集合

集合 视图显示垃圾回收期间收集或保留的对象数。

集合视图的屏幕截图。

以下信息显示在 集合 视图中。

  • GC”列显示可执行文件生命周期中此垃圾回收的 ID。
  • 生成”列显示垃圾回收的生成。
  • GC 类型”列显示此垃圾回收的类型。
  • GC 原因”列显示此垃圾回收事件的原因。
  • 暂停持续时间”列显示由于垃圾回收器需要独占使用堆而阻止执行的时间。 对于后台垃圾回收,此值较小。
  • LOH 大小”列显示运行垃圾回收器后大型对象堆的大小。
  • POH 大小”列显示运行垃圾回收器后固定的对象堆的大小。
  • 可终结 Surv (MB)”列显示具有在垃圾回收中幸存的终结器(析构函数)的对象 MB 数。
  • 固定对象”列显示此垃圾回收提升的固定对象数。
  • “已收集”列显示了垃圾回收器收集的对象数
  • “已保留”列显示了运行垃圾回收器后保留的对象数

选择行时,此视图还会显示饼图,以便按类型直观展示收集的对象和存活的对象。

“集合”视图中饼图的屏幕截图。

筛选工具

“分配”、“调用树”和“函数”视图都包含“仅显示我的代码”和“显示本机代码”选项,以及一个筛选器框。

  • 显示“仅我的代码” 将系统、框架和其他非用户代码折叠到 [外部代码] 帧中,以便仅专注于代码。 有关详细信息,请参阅使用“仅我的代码”调试用户代码
  • 显示本机代码 在分析目标中显示本机代码,并且可以包含非用户代码。
  • 通过筛选器框,可根据你提供的值来筛选“名称”或“函数名称”列。 在框中输入字符串值。 然后,该表仅显示包含该字符串的类型。