一篇文章教你如何排查.NET内存泄漏

2022-04-14 17:37:45
目录
前言检查托管内存使用p collect -p 4807Writing minidump with heap to ./core_20190430_185145Complete

分析 core dump

接下来可以使用 dotnet-dump analyze 对已生成的dump文件进行分析。

dotnet-dump analyze core_20190430_185145

这里的 core_20190430_185145 就是你想要分析的dump名,值得一提的是:如果你遇到了 libdl.so cannot be found 错误,建议以安装一下  libc6-dev package 包。

首先我们通过 sos 命令查看 托管堆 上的所有对象统计清单。

> dumpheap -statStatistics:              MT    Count    TotalSize Class Name...00007f6c1eeefba8      576        59904 System.Reflection.RuntimeMethodInfo00007f6c1dc021c8     1749        95696 System.SByte[]00000000008c9db0     3847       116080      Free00007f6c1e784a18      175       128640 System.Char[]00007f6c1dbf5510      217       133504 System.Object[]00007f6c1dc014c0      467       416464 System.Byte[]00007f6c21625038        6      4063376 testwebapi.Controllers.Customer[]00007f6c20a67498   200000      4800000 testwebapi.Controllers.Customer00007f6c1dc00f90   206770     19494060 System.StringTotal 428516 objects

 

从输出看,大头都是些 String 和 Customer 对象,然后可以通过 mt 参数来获取该方法表下所有的实例对象。

> dumpheap -mt 00007faddaa50f90         Address               MT     Size...00007f6ad09421f8 00007faddaa50f90       94...00007f6ad0965b20 00007f6c1dc00f90       8000007f6ad0965c10 00007f6c1dc00f90       8000007f6ad0965d00 00007f6c1dc00f90    http://www.easck.com   8000007f6ad0965df0 00007f6c1dc00f90       8000007f6ad0965ee0 00007f6c1dc00f90       80Statistics:              MT    Count    TotalSize Class Name00007f6c1dc00f90   206770     19494060 System.StringTotal 206770 objects

接下来可以用 !gcroot 查看某一个string到底被谁持有着?

> gcroot -all 00007f6ad09421f8Thread 3f68:    00007F6795BB58A0 00007F6C1D7D0745 System.Diagnostics.Tracing.CounterGroup.PollForValues() [/_/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/CounterGroup.cs @ 260]        rbx:  (interior)            ->  00007F6BDFFFF038 System.Object[]            ->  00007F69D0033570 testwebapi.Controllers.Processor            ->  00007F69D0033588 testwebapi.Controllers.CustomerCache            ->  00007F69D00335A0 System.Collections.Generic.List`1[[testwebapi.Controllers.Customer, DiagnosticScenarios]]            ->  00007F6C000148A0 testwebapi.Controllers.Customer[]            ->  00007F6AD0942258 testwebapi.Controllers.Customer            ->  00007F6AD09421F8 System.StringHandleTable:    00007F6C98BB15F8 (pinned handle) qckIEZRP   -> 00007F6BDFFFF038 System.Object[]    -> 00007F69D0033570 testwebapi.Controllers.Processor    -> 00007F69D0033588 testwebapi.Controllers.CustomerCache    -> 00007F69D00335A0 System.Collections.Generic.List`1[[testwebapi.Controllers.Customer, DiagnosticScenarios]]    -> 00007F6C000148A0 testwebapi.Controllers.Customer[]    -> 00007F6AD0942258 testwebapi.Controllers.Customer    -> 00007F6AD09421F8 System.StringFound 2 roots.

从string的引用链看,它是被 CustomerCache 所持有,然后就可以到代码中寻找问题啦。

原文链接:https://docs.microsoft.com/en-us/dotnet/core/diagnostics/debug-memory-leak

总结