分析发布版本中的内存使用情况(C#、Visual Basic、C++、F#)

内存使用情况 工具监视应用的内存使用情况。 可以使用该工具来研究你在 Visual Studio 中积极开发的方案的实时内存效果。 可以拍摄应用内存状态的详细快照,并比较快照以查找内存问题的根本原因。 “内存使用”工具支持在 .NET、ASP.NET、C++ 或混合模式(.NET 和本机)应用上使用。

内存使用工具可以在版本或调试内部版本上运行。 本文介绍如何在 Visual Studio 性能探查器中使用内存使用情况工具,这是建议用于发布版本的。 有关根据需要选择最佳内存分析工具的信息,请参阅 选择内存分析工具

若要获得最佳本文档体验,请从文章顶部的列表中选择首选开发语言或运行时。

内存使用情况诊断会话

启动内存使用情况诊断会话:

  1. 在 Visual Studio 中打开项目。

    内存使用情况工具支持 .NET、ASP.NET、C++ 或混合模式(.NET 和本机)应用。

  2. 在“调试”菜单中,将解决方案配置设置为“发布”,然后选择 本地 Windows 调试器(或 本地计算机)作为部署目标。

  3. 在菜单栏上,选择“调试”>“性能探查器”。

  4. 在“可用工具”下,选择“内存使用情况”,然后选择“启动”

    启动内存使用情况诊断会话。

    启动内存使用情况诊断会话。

监视内存使用情况

启动诊断会话时,应用将启动,诊断工具 窗口显示应用内存使用情况的时间线图。

Visual Studio 性能探查器中“诊断工具”窗口的屏幕截图,其中显示了应用的内存使用时间线图。

Visual Studio 性能探查器中“诊断工具”窗口的屏幕截图,其中显示了应用的内存使用时间线图。

时间线图显示应用运行时的内存波动。 图形中的峰值通常表示某些代码正在收集或创建数据,然后在处理完成后将其丢弃。 大峰值指示可以优化的区域。 主要问题是内存消耗增加,且不会返回。 这可能表示内存使用率低下,甚至内存泄漏。

拍摄应用内存状态的快照

应用使用大量对象,你可能希望将分析集中在一个方案中。 或者,可能会发现要调查的内存问题。 可以在诊断会话期间拍摄快照,以在特定时刻捕获内存使用情况。 最好在出现内存问题之前获取应用的基线快照。 可以在第一次出现问题后创建另一个快照,如果可以重复此方案,则可以创建其他快照。

若要收集快照,请在您想要捕获内存数据时选择 拍摄快照

拍摄快照的屏幕截图。

关闭诊断会话

若要在不创建报表的情况下停止监视会话,只需关闭诊断窗口。 若要在完成收集或拍摄快照后生成报表,请选择 停止收集

停止收集的屏幕截图。

停止收集的屏幕截图。

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

内存使用情况报告

停止数据收集后,内存使用情况 工具将停止应用,并显示 内存使用情况 概述页。

Visual Studio 性能探查器内存使用情况工具中概述页的屏幕截图,其中显示了内存使用情况图和两个快照窗格。

Visual Studio 性能探查器内存使用情况工具中概述页的屏幕截图,其中显示了内存使用情况图和两个快照窗格。

内存使用情况快照

快照 窗格中的数字显示创建每个快照时内存中的对象和字节数,以及快照与上一个快照之间的差异。

这些数字是链接,可以在新的 Visual Studio 窗口中打开详细的 内存使用 报告视图。 快照详细信息报表 显示一个快照中的类型和实例。 快照差异报表会比较两个快照中的类型和实例。

快照视图链接的屏幕截图

对于 C++,“对象(差异)”列名为“分配(差异)”

图像 描述
步骤 1 拍摄快照时内存中的对象总数。 选择此链接可显示按类型实例计数排序的快照详细信息报表。
步骤 2 此快照中的内存对象总数与上一快照之间的差异。 选择此链接可显示按类型实例总数差异排序的快照差异报表。
步骤 3 拍摄快照时内存中的字节总数。 选择此链接可显示按类型实例的总大小排序的快照详细信息报表。
步骤 4 此快照中内存对象的总大小与上一快照之间的差异。 正数表示此快照的内存大小大于前一个快照,负数表示大小较小。 “基线”表示快照是诊断会话中的第一个快照无差异 表示差异为零。 选择此链接可显示按类型实例总大小差异排序的快照差异报表。

快照视图链接

图像 描述
步骤 1 拍摄快照时内存中的字节总数。 选择此链接可显示按类型实例的总大小排序的快照详细信息报表。
步骤 2 拍摄快照时内存中的对象总数。 选择此链接可显示按类型实例计数排序的快照详细信息报表。
步骤 3 此快照中内存对象的总大小与上一快照之间的差异。 正数表示此快照的内存大小大于前一个快照,负数表示大小较小。 “基线”表示快照是诊断会话中的第一个快照无差异 表示差异为零。 选择此链接可显示按类型实例总大小差异排序的快照差异报表。
步骤 4 此快照中的内存对象总数与上一快照之间的差异。 选择此链接可显示快照差异报表。 它按类型实例总数的差进行排序。

托管类型报告

选择内存使用情况摘要表中 对象(差异) 单元格的当前链接。

托管类型报表的屏幕截图。

说明

对于 .NET 代码,视图实例 图标(对象类型列中的实例图标)仅在使用 调试器集成的内存使用情况工具 或打开 堆快照 并选择 调试托管内存时可用。

顶部窗格会显示快照中类型的计数和大小,包括由类型引用的所有对象的大小(“非独占大小”)。

底部窗格中的 “根的路径” 树显示引用上部窗格中选择的类型的对象。 仅当引用对象的最后一个类型已发布时,.NET 垃圾回收器才会清理对象的内存。 有关使用“根的路径”树的详细信息,请参阅分析根的热路径

托管类型报表的屏幕截图。

顶部窗格会显示快照中类型的计数和大小,包括由类型引用的所有对象的大小(“非独占大小”)。

底部窗格中的 “根的路径” 树显示引用上部窗格中选择的类型的对象。 仅当引用对象的最后一个类型已发布时,.NET 垃圾回收器才会清理对象的内存。

“引用的类型” 树显示上部窗格中选择的类型所持有的引用。

引用对象报表的屏幕截图。

“引用的类型” 树显示上部窗格中选择的类型所持有的引用。

引用对象报表的屏幕截图。

报告树筛选器

当应用开发人员在调查内存问题时,应用中的许多类型并非必需。 快照报表筛选器可以将大多数这些类型隐藏在“托管内存”和“根的路径”树的路径中

排序和筛选选项

内存使用情况排序和筛选排序和筛选选项

  • 若要按类型名称筛选树,请在 筛选器 框中输入名称。 筛选器不区分大小写,并且它可以识别类型名称的任何部分中的指定字符串。

  • 筛选器 下拉列表中选择“仅显示我的代码”,以隐藏由外部代码生成的大多数实例。 外部类型属于操作系统或框架组件,或由编译器生成。

  • 在“筛选器”下拉列表中选择“隐藏小型对象”以隐藏以隐藏其大小(字节)小于内存总数 0.5% 的类型

本机类型报告

在“诊断工具”窗口的内存使用率摘要表中,选择“分配(差异)”或“堆大小(差异)”单元格的当前链接

本类型视图的屏幕截图。

本类型视图的屏幕截图。

类型视图 显示快照中类型的数量和大小。

  • 选择所选类型旁边的 视图实例 图标,以显示有关快照中所选类型对象的信息。

    实例 视图显示所选类型的每个实例。 选择实例时,将在 分配调用堆栈 窗格中显示导致实例创建的调用堆栈。 (此信息仅在调试时可用。

    “实例”视图和“分配调用堆栈”窗格的屏幕截图。

  • 选择实例图标(所选类型的对象类型列中的实例图标)以显示有关快照中所选类型的对象的信息。

    实例 视图显示所选类型的每个实例。 选择实例时,将在 分配调用堆栈 窗格中显示创建该实例所导致的调用堆栈。

    “实例”视图和“分配调用堆栈”窗格的屏幕截图。

  • 选择 堆栈 以查看所选类型的分配堆栈。

    堆栈视图的屏幕截图。

  • 视图模式 列表中选择 堆栈视图,以查看所选类型的分配堆栈。

    堆栈视图的屏幕截图。

内存使用情况见解

对于托管内存,内存分析工具还提供多个功能强大的内置自动见解。 选择托管类型报表中的“见解” 选项卡,并显示适用的自动见解,例如 重复字符串稀疏数组,以及 事件处理程序泄漏

内存使用情况工具中见解视图的屏幕截图。

“重复字符串”部分显示了在堆上多次分配的字符串列表。 此外,本部分显示总浪费的内存,即字符串大小的(实例数 - 1) 倍。

稀疏数组 部分显示主要填充零个元素的数组,在性能和内存使用方面可能效率低下。 内存分析工具将自动检测这些数组,并显示由于这些零值而浪费多少内存。

Visual Studio 2022 版本 17.9 预览版 1 中提供的 事件处理程序泄漏 部分显示一个对象订阅另一个对象的事件时可能发生的潜在内存泄漏。 如果事件发布者的生存期超过了订阅者的生存期,即使没有对订阅者的其他引用,订阅者仍会保持活动状态。 这可能会导致内存泄漏,其中未使用的内存未正确释放,导致应用程序随着时间的推移使用越来越多的内存。

已知某些类型具有可以读取的字段,用于确定它们所持有的本机内存大小。 Insights 选项卡展示了对象图中的虚假本机内存节点,这些节点由其父对象保留在内,使得UI能够识别它们并展示其大小和引用图。

内存使用情况工具中“原生洞察视图”的屏幕截图。

更改(差异)报告

  • 在内存使用概述页面的“快照”窗格的单元格中,单击“更改”链接

    选择单元格中的更改链接的屏幕截图。

    选择单元格中的更改链接的屏幕截图。

  • 在托管或本机报告的 “与之比较的对象” 列表中选择快照。

    从“比较对象”列表中选择快照的屏幕截图。

    从“比较对象”列表中选择快照的屏幕截图。

更改报告会向基本报告添加一些列(使用 “(差异)”进行标记),这些列显示基本快照值与比较快照之间的差异。 下面是本机类型视图差异报告可能会采用的外观:

本机类型差异视图的屏幕截图。

本机类型差异视图的屏幕截图。

顶部窗格会显示快照中类型的计数和大小,包括由类型引用的所有对象的大小(“非独占大小”)。