.NetCore中dump文件的创建和分析

发布时间 2023-07-29 11:33:46作者: 丝絮

1、通过程序生成dump文件

  安装nuget包:Microsoft.Diagnostics.NETCore.Client

  生成dump文件代码:

  var client = new DiagnosticsClient(Environment.ProcessId);

client.WriteDump(DumpType.Full,Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dumps","1.dump"));

生成的dump文件位于根目录dumps/1.dump

2、procdump根据条件生成dump

 可在linux机器安装procdump(https://github.com/Sysinternals/ProcDump-for-Linux/blob/master/INSTALL.md),并设置抓取条件,如:

procdump -ma -c 30 -m 1024 -s 3 -n 2 -e 1 -f "" 1526(Process Name or PID) -o /tmp

  -ma 生成full dump, 即包括进程的所有内存. 默认的dump格式包括线程和句柄信息.

  -c 在CPU使用率到达这个阀值的时候, 生成dump文件.

  -m 在内存到达这个阀值的时候(MB单位), 生成dump文件.

  -s CPU阀值必须持续多少秒才抓取dump文件.

   -n 在该工具退出之前要抓取多少个dump文件.

   -o dump文件保存目录.

进程ID为linux主机查看的服务进程ID,也可以在制作docker 镜像时加入Dockerfile中,此时进程ID为1(容器中进程ID)

Dockerfile中加入procdump指令并指定条件生成:

# 安装所需依赖

RUN apt-get update \

    && apt-get install -y --no-install-recommends \

        wget \

        gdb \

        lldb

# 安装 procdump

RUN wget https://packages.microsoft.com/repos/microsoft-debian-buster-prod/pool/main/p/procdump/procdump_1.1.1-220_amd64.deb -O procdump.deb \

    && dpkg -i procdump.deb \

&& rm procdump.deb

RUN procdump -ma -c 30 -m 1024 -s 3 -n 2 -e 1 -f "" 1(Process Name or PID) -o /tmp

3、Docker 中服务创建dump

Docker exec -it 容器id /bin/bash,执行命令:

/usr/share/dotnet/shared/ Microsoft.NETCore.App/6.0.13(sdk版本)/createdump 1

收集的dump文件存在路径为/tmp/coredump.1

4、本地安装dotnet-dump

dotnet tool install --global dotnet-dump

5、开始分析dump文件:

  1) 加载文件  dotnet-dump analyze 文件路径(coredump.1)

      2)  利用clrstack -all分析堆栈 查看当前工作线程

  3) 分析内存 利用dumpheap -stat查看堆栈信息

  分别对应 MT Count TotalSize Class Name

找到后面TotalSize最大的几个对象。

例如System.String占比比较大,进一步分析mt对象。

dumpheap -mt 7ff036a1d2e0

分别对应Address MT Size

找到Size最大的Address进一步分析使用对象:

gcroot -all 7fed5ffff038  或 do 7fed5ffff038