Posted in

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

一、前提条件

  • 定位环境:生产环境
  • .NET Core 3.1 SDK 或更高版本。
  • dotnet-counters 检查托管内存的使用情况。
  • dotnet-dump 收集和分析转储文件。
请添加图片描述

二、排查步骤

1. 项目准备

  1. 创建内存溢出的项目

2. dotnet-counters准备

  1. 先安装dotnet-countersdotnet tool install –global dotnet-counters
    在这里插入图片描述
  2. 然后找到进程编号dotnet-counters ps
    在这里插入图片描述
  3. 然后监视进程dotnet-counters monitor –refresh-interval 1 -p 10232 (进程编号)
    在这里插入图片描述
  4. 最后查看显示统计信息找到 GC Heap Size 。然后统计这个程序的增长,为了找出内存泄露的代码
    在这里插入图片描述
    在这里插入图片描述

3. dotnet-dump准备

  1. 先安装dotnet-countersdotnet tool install –global dotnet-dump
    在这里插入图片描述
  2. 然后生成转储文件(内存文件)dotnet-dump collect -p 10232 (进程编号)
    在这里插入图片描述
  3. 然后分析转储文件dotnet-dump analyze dump_20210825_225811.dmp(转储文件名)
    在这里插入图片描述
请添加图片描述

三、结果分析

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

dumpheap -stat
在这里插入图片描述
直接拉到最下面,看最大的对象
在这里插入图片描述

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

dumpheap -mt 00007ffe88612360 为类型编号
在这里插入图片描述

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

gcroot -all 000002c054600480 对象编号
随便找一个引用,以最后一个来看

在这里插入图片描述

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

在这里插入图片描述

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

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注