.NetCore中dump文件的创建和分析
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