堆分析工具 (dotnet-gcdump)

本文适用于:✔️ dotnet-gcdump 版本 3.1.57502 及更高版本

安装

可采用两种方法来下载和安装 dotnet-gcdump

注意

若要在 x86 应用上使用 dotnet-gcdump,需要使用相应的 x86 版本的工具。

摘要

dotnet-gcdump [-h|--help] [--version] <command>

说明

dotnet-gcdump 全局工具使用 EventPipe 收集实时 .NET 进程的 GC(垃圾回收器)转储。 创建 GC 转储时需要在目标进程中触发 GC、开启特殊事件并从事件流中重新生成对象根图。 此过程允许在进程运行时以最小的开销收集 GC 转储。 这些转储对于以下几种情况非常有用:

  • 比较多个时间点堆上的对象数。
  • 分析对象的根(回答诸如“还有哪些引用此类型的内容?”等问题)。
  • 收集有关堆上的对象计数的常规统计信息。

查看从 dotnet-gcdump 捕获的 GC 转储

在 Windows 上,可以在 PerfView 中查看 .gcdump 文件,以便进行分析,也可在 Visual Studio 中查看该文件。 目前,无法在非 Windows 平台上打开 .gcdump

可以收集多个 .gcdump,并在 Visual Studio 中同时打开它们以获取比较体验。

选项

  • --version

    显示 dotnet-gcdump 实用工具的版本。

  • -h|--help

    显示命令行帮助。

命令

Command
dotnet-gcdump collect
dotnet-gcdump ps
dotnet-gcdump report

dotnet-gcdump collect

从当前正在运行的进程中收集 GC 转储。

警告

为了遍历 GC 堆,此命令将触发第 2 代(完整)垃圾回收,这可能会使运行时长时间挂起,尤其是在 GC 堆很大的情况下。 如果 GC 堆很大,请不要在对性能要求高的环境中使用此命令。

摘要

dotnet-gcdump collect [-h|--help] [-p|--process-id <pid>] [-o|--output <gcdump-file-path>] [-v|--verbose] [-t|--timeout <timeout>] [-n|--name <name>]

选项

  • -h|--help

    显示命令行帮助。

  • -p|--process-id <pid>

    可从中收集 GC 转储的进程 ID。

  • -o|--output <gcdump-file-path>

    应写入收集 GC 转储的路径。 默认为 .\YYYYMMDD_HHMMSS_<pid>.gcdump。

  • -v|--verbose

    收集 GC 转储时输出日志。

  • -t|--timeout <timeout>

    如果收集 GC 转储的时间超过了此秒数,则放弃收集。 默认值为 30。

  • -n|--name <name>

    可从中收集 GC 转储的进程的名称。

注意

在 Linux 和 macOS 上,此命令需要目标应用程序和 dotnet-gcdump 使用同一 TMPDIR 环境变量。 否则,该命令将超时。

注意

若要使用 dotnet-gcdump 收集 GC 转储,需要以与运行目标进程的用户相同的用户身份或以根身份运行。 否则,该工具将无法与目标进程建立连接。

dotnet-gcdump ps

列出可为其收集 GC 转储的 dotnet 进程。 dotnet-gcdump 6.0.320703 及更高版本还显示每个进程的启动命令行参数(如果可用)。

摘要

dotnet-gcdump ps [-h|--help]

示例

假设使用命令 dotnet run --configuration Release 启动长时间运行的应用。 在另一个窗口中,运行 dotnet-gcdump ps 命令。 你将看到如下输出。 命令行参数(如果有)显示在 dotnet-gcdump 版本 6.0.320703 及更高版本中。

> dotnet-gcdump ps
  
  21932 dotnet     C:\Program Files\dotnet\dotnet.exe     run --configuration Release
  36656 dotnet     C:\Program Files\dotnet\dotnet.exe

dotnet-gcdump report <gcdump_filename>

从以前生成的 GC 转储或从正在运行的进程生成报表,并将其写入 stdout

摘要

dotnet-gcdump report [-h|--help] [-p|--process-id <pid>] [-t|--report-type <HeapStat>]

选项

  • -h|--help

    显示命令行帮助。

  • -p|--process-id <pid>

    可从中收集 GC 转储的进程 ID。

  • -t|--report-type <HeapStat>

    可生成报表的类型。 可用选项:heapstat(默认)。

疑难解答

  • gcdump 中没有类型信息。

    在 .NET Core 3.1 之前,存在一个问题,即使用 EventPipe 调用 gcdump 时,gcdump 之间的类型缓存没有清除。 这导致确定类型信息所需的事件未发送给第二个和后续 gcdump。 此问题已在 .NET Core 3.1-preview2 中得以修复。

  • COM 和静态类型不在 GC 转储中。

    在 .NET Core 3.1 之前,存在一个问题,即通过 EventPipe 调用 GC 转储时,不会发送静态和 COM 类型。 此问题已在 .NET Core 3.1 中得以修复。

  • 由于缺少信息,dotnet-gcdump 无法生成 .gcdump 文件,例如,[Error] Exception during gcdump: System.ApplicationException:ETL 文件显示了堆转储的开始,但没有显示其完成。 或者,.gcdump 文件不包括整个堆。

    dotnet-gcdump 通过垃圾回收器在引发第 2 代回收期间发送的事件跟踪来工作。 如果堆足够大,或者没有足够的内存来缩放事件缓冲区,则可以删除从跟踪重新构造堆图所需的事件。 在这种情况下,若要诊断堆出现的问题,建议收集进程的转储。

  • 在内存受限的环境中,dotnet-gcdump 似乎会导致内存不足的问题。

    dotnet-gcdump 通过垃圾回收器在引发第 2 代回收期间发送的事件跟踪来工作。 事件集合的缓冲区由目标应用程序拥有,最多可增长至 256 MB。 dotnet-gcdump 本身也使用内存。 如果环境受到内存限制,请务必在收集 gcdump 时考虑这些因素以防止出现错误。