● 公司核心系统内存泄露排查
- 公司核心系统内存泄露排查
- 公司核心系统内存泄露排查(后续)
- 公司核心系统"内存泄露"排查(完结)
查找内存泄露
之前写了个系统监控的程序,在某次升级一个项目后,每隔2个月左右会收到服务器的监控提醒,使用top
命令查询发现一个核心asp.net core web api内存异常。
api仅有两个功能,简单却很重要,主要负责承上启下:
- redis subscribe/publish
- 作为路由使用http(s)中转所有项目后端接口数据
每次在收到提醒邮件后,到服务器准备用dotnet-dump
转储文件时,都会报错Writing dump failed (HRESULT: 0x80004005)
,估计是剩余内存不足以进行分析。
只能检查自己的代码,检查过2次代码都没查出问题。因为避开了HttpClient的坑,所以一直怀疑第三方redis库出的问题,但是api没有任何报错,有几次在api重启后几天一直观察,没有发现内存上升,一直无法定位bug具体在哪里。遇到这种提醒,只能重启进程先解决问题,防止系统宕机。
今天突然想起来距离上次报错已经1个月了。查了下服务器,api内存占用19%,已经比较高了。top
命令获取到pid为10680,试了下dotnet-dump
可以正常使用。
dotnet-dump collect -p 10680
Writing full to /root/core_20220511_092512
Complete
文件大小:1.8G 😳
分析核心转储
进入交互式shell开始分析文件内容:
dotnet-dump analyze core_20220511_092512
查看大于10M的对象信息,可以看到CSRedis占用了大量的内存:
dumpheap -stat -min 10240
可以用 !gcroot 查看某一个object到底被谁持有:
gcroot -all xxxxx
最后确认罪魁祸首就是第三方库CSRedis,nuget没有新版本。找到了项目的GitHub,发现项目已经在2021年停止维护,作者已经重写了一个新项目FreeRedis😕。不太想用FreeRedis试错,也不想看作者源码找bug了,估计也看不懂😵。
CSRedis的ConcurrentQueue不知道是不是使用后没释放,导致数据越来越多,今天先使用GC.Collect()
垃圾回收机制试下,如果过段时间还出现内存泄露,就只能把CSRedis替换掉才能彻底解决。
-END-