在生产环境中,.Net如何定位系统内存泄露具体位置

文章目录

一、前提条件

二、排查步骤

1. 项目准备

2. dotnet-counters准备

3. dotnet-dump准备

三、结果分析

1. 找到内存比较大的类型,通过查看内存占用大小和对象数量.

2. 然后分析类型具体对象

3. 然后找出的应用根(目的是找出在哪里被引用了)

一、前提条件

定位环境:生产环境

.NET Core 3.1 SDK 或更高版本。

dotnet-counters 检查托管内存的使用情况。

dotnet-dump 收集和分析转储文件。

二、排查步骤

1. 项目准备

创建内存溢出的项目

2. dotnet-counters准备

先安装dotnet-counters

dotnet tool install --global dotnet-counters

在生产环境中,.Net如何定位系统内存泄露具体位置

然后找到进程编号

在生产环境中,.Net如何定位系统内存泄露具体位置

dotnet-counters ps

然后监视进程

dotnet-counters monitor --refresh-interval 1 -p 10232 (进程编号)

在生产环境中,.Net如何定位系统内存泄露具体位置

最后查看显示统计信息

找到 GC Heap Size 。然后统计这个程序的增长,为了找出内存泄露的代码

在生产环境中,.Net如何定位系统内存泄露具体位置

在生产环境中,.Net如何定位系统内存泄露具体位置

3. dotnet-dump准备

先安装dotnet-counters

dotnet tool install --global dotnet-dump

在生产环境中,.Net如何定位系统内存泄露具体位置

然后生成转储文件(内存文件)

dotnet-dump collect -p 10232 (进程编号)

在生产环境中,.Net如何定位系统内存泄露具体位置

然后分析转储文件

dotnet-dump analyze dump_20210825_225811.dmp(转储文件名)

在生产环境中,.Net如何定位系统内存泄露具体位置

三、结果分析

1. 找到内存比较大的类型,通过查看内存占用大小和对象数量

dumpheap -stat

在生产环境中,.Net如何定位系统内存泄露具体位置

直接拉到最下面,看最大的对象

在生产环境中,.Net如何定位系统内存泄露具体位置

2. 然后分析类型具体对象

dumpheap -mt 00007ffe88612360 为类型编号

在生产环境中,.Net如何定位系统内存泄露具体位置

3. 然后找出的应用根(目的是找出在哪里被引用了)

gcroot -all 000002c054600480 对象编号

随便找一个引用,以最后一个来看

在生产环境中,.Net如何定位系统内存泄露具体位置

到这一步已经可以排查出是Employee里边导致的,接着排查代码

在生产环境中,.Net如何定位系统内存泄露具体位置

这里数据没能GC回收是由于对象的运行时间比析构队列的长导致GC无法回收,实际上可能有其他稀奇古怪的各种原因,定位到代码以后剩下的都好排查了。