菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
0
0

使用dotnet-dump分析dotnet转储文件

原创
05/13 14:22
阅读数 735

课程推荐:web全栈开发就业班--拿到offer再缴学费--融职教育

有很多时候,在生产环境会产生各种各样的问题,但在生成环境计划是不能调试的,所以dotnet-dump这时就启动作用了。

除了dotnet-dump外,windows下windbg,linux下的lldb是更为强大的分析工具。

微软的文档:

https://docs.microsoft.com/zh-cn/dotnet/core/diagnostics/dotnet-dump

开始使用dotnet-dump

假设一种情况,在生成环境中线程数高,且内存溢出。

public IActionResult Index()
{
_logger.LogInformation("新增一条线程。");
Task.Run(() =>
{
// 添加1Mb。
while (true)
{
_logger.LogInformation("添加1Mb");
var buff = new byte[1024 * 1024];
for (int i = 0; i < buff.Length; i++)
{
buff[i] = 0;
}

                _byteBag.Add(buff);
                SpinWait.SpinUntil(() => false, 10000);
            }
        });

        return View();
    }

以上简单的设置一下,然后浏览器多刷几次。

技术图片

每刷新一次,则线程数加1,要知道系统有线程数限制,超过极限后会爆炸。

使用dotnet-dump分析
第一步收集转储文件

dotnet-dump collect -p 10504 -o dump
技术图片

第二部分析转储文件

dotnet-dump analyze dump
技术图片

分析:

clrthreads
ThreadCount: 39
UnstartedThread: 0
BackgroundThread: 38
PendingThread: 0
DeadThread: 0
Hosted Runtime: no
Lock
DBG ID OSID ThreadOBJ State GC Mode GC Alloc Context Domain Count Apt Exception
20 1 1f34 000001BE985BEF50 202a020 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 MTA
32 2 32dc 000001C3A69D50D0 2b220 Preemptive 000001C258931410:000001C258931668 000001BE96B95A10 0 MTA (Finalizer)
27 3 2488 000001C3A6A0F500 102a220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 MTA (Threadpool Worker)
52 7 4b90 000001C3A6BEF8F0 202b220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 MTA
29 14 29e4 000001C3A7286CB0 3029220 Preemptive 000001BFD8936AE8:000001BFD89389C0 000001BE96B95A10 0 MTA (Threadpool Worker)
41 16 3c38 000001C3A7286010 3029220 Preemptive 000001C0989349E0:000001C098934BE8 000001BE96B95A10 0 MTA (Threadpool Worker)
1 18 798 000001C3A7401180 3029220 Preemptive 000001C0589317B8:000001C058931CF8 000001BE96B95A10 0 MTA (Threadpool Worker)
58 19 4ee0 000001C3A73FD260 3029220 Preemptive 000001BF58931900:000001BF58931AC8 000001BE96B95A10 0 MTA (Threadpool Worker)
11 20 1594 000001C3A73FF1F0 3029220 Preemptive 000001C2189324A0:000001C218932738 000001BE96B95A10 0 MTA (Threadpool Worker)
9 21 12c0 000001C3A74004E0 3029220 Preemptive 000001C118931A60:000001C118931AC0 000001BE96B95A10 0 MTA (Threadpool Worker)
17 22 1a44 000001C3A73FBF70 3029220 Preemptive 000001BED8931938:000001BED8931970 000001BE96B95A10 0 MTA (Threadpool Worker)
53 23 4d0c 000001C3A73FCC10 3029220 Preemptive 000001C258932770:000001C258932B10 000001BE96B95A10 0 MTA (Threadpool Worker)
12 24 1648 000001C3A73FD8B0 3029220 Preemptive 000001BFD8934BF8:000001BFD89369C0 000001BE96B95A10 0 MTA (Threadpool Worker)
55 25 4d4c 000001C3A73FC5C0 3029220 Preemptive 000001BE98932F40:000001BE98933590 000001BE96B95A10 0 MTA (Threadpool Worker)
31 26 2ff0 000001C3A73FFE90 3029220 Preemptive 000001BF18933560:000001BF18933578 000001BE96B95A10 0 MTA (Threadpool Worker)
7 27 11b0 000001C3A73FEBA0 3029220 Preemptive 000001C198932150:000001C198932510 000001BE96B95A10 0 MTA (Threadpool Worker)
59 28 4fc0 000001C3A73FDF00 3029220 Preemptive 000001C218933848:000001C218935258 000001BE96B95A10 0 MTA (Threadpool Worker)
35 29 35bc 000001C3A73FE550 3029220 Preemptive 000001C2189330D8:000001C2189331D0 000001BE96B95A10 0 MTA (Threadpool Worker)
10 30 12dc 000001C3A73FF840 3029220 Preemptive 000001BF98931900:000001BF98932140 000001BE96B95A10 0 MTA (Threadpool Worker)
34 33 34fc 000001C3A73F9FE0 3029220 Preemptive 000001BFD8932FB0:000001BFD89349C0 000001BE96B95A10 0 MTA (Threadpool Worker)
56 15 4da4 000001C3A73FA630 21220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 Ukn
6 35 ef8 000001C3A73FAC80 21220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 Ukn
50 36 492c 000001C3A73FB920 21220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 Ukn
21 37 2048 000001C3A7285370 21220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 Ukn
13 38 18f0 000001C3A6C23470 21220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 Ukn
40 39 3ac8 000001C3A6C22E20 21220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 Ukn
15 40 1974 000001C3A6C23AC0 21220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 Ukn
8 41 1200 000001C3A6C24110 21220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 Ukn
4 42 a94 000001C3A6C22180 21220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 Ukn
43 43 4220 000001C3A6C227D0 21220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 Ukn
26 44 2480 000001C3A6C24760 21220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 Ukn
30 45 2d1c 000001C3A6C21B30 21220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 Ukn
33 46 3498 000001C3A6C24DB0 21220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 Ukn
5 47 bd8 000001C3A6C25400 21220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 Ukn
38 48 3610 000001C3A76DC0C0 21220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 Ukn
18 49 1da0 000001C3A76DB420 21220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 Ukn
36 34 35d0 000001C3A76DADD0 8029220 Preemptive 000001C058932268:000001C058933CF8 000001BE96B95A10 0 MTA (Threadpool Completion Port)
49 31 4778 000001C3A76D9AE0 1029220 Preemptive 000001C1D8938958:000001C1D8938C38 000001BE96B95A10 0 MTA (Threadpool Worker)
14 32 1904 000001C3A76D6860 8029220 Preemptive 0000000000000000:0000000000000000 000001BE96B95A10 0 MTA (Threa
分析线程

49 31 4778 000001C3A76D9AE0 1029220 Preemptive 000001C1D8938958:000001C1D8938C38 000001BE96B95A10 0 MTA (Threadpool Worker)

setthread 31
clrstack
OS Thread Id: 0x2ff0 (31)
Child SP IP Call Site
000000AEC14FE0A8 00007ffd1ee8c414 [HelperMethodFrame: 000000aec14fe0a8] System.Threading.Thread.SleepInternal(Int32)
000000AEC14FE1A0 00007FFC6C1438CD System.Threading.SpinWait.SpinOnceCore(Int32)
000000AEC14FE250 00007FFC6C1811E7 System.Threading.SpinWait.SpinUntil(System.Func1<Boolean>, Int32) 000000AEC14FE2A0 00007FFC6BF23560 DotnetDump.Controllers.HomeController.<Index>b__3_0() [E:\Test\DotnetDump\Controllers\HomeController.cs @ 40] 000000AEC14FE340 00007FFCCAB2C01F System.Threading.Tasks.Task1[[System.Canon, System.Private.CoreLib]].InnerInvoke()
000000AEC14FE380 00007FFCCAA38092 System.Threading.Tasks.Task+<>c.<.cctor>b
274_0(System.Object)
000000AEC14FE3B0 00007FFCCAA38012 System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(System.Threading.Thread, System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
000000AEC14FE400 00007FFCCAA37CE7 System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef, System.Threading.Thread)
000000AEC14FE4A0 00007FFCCAA37BC3 System.Threading.Tasks.Task.ExecuteEntryUnsafe(System.Threading.Thread)
000000AEC14FE4E0 00007FFCCAA37B5B System.Threading.Tasks.Task.ExecuteFromThreadPool(System.Threading.Thread)
000000AEC14FE510 00007FFC6C149BF1 System.Threading.ThreadPoolWorkQueue.Dispatch()
000000AEC14FE990 00007ffccb0b6ba3 [DebuggerU2MCatchHandlerFrame: 000000aec14fe990]
通过此方法分析线程调用栈。由于有pdb文件,因此可以很方便的看到具体的错误信息。

使用clrsatck -a

找到

000000AEC14FE2A0 00007FFC6BF23560 DotnetDump.Controllers.HomeController.b__3_0() [E:\Test\DotnetDump\Controllers\HomeController.cs @ 40]
PARAMETERS:
this (0x000000AEC14FE340) = 0x000001c0589e6a40
LOCALS:
0x000000AEC14FE318 = 0x000001c2dc831e00
0x000000AEC14FE314 = 0x0000000000100000
0x000000AEC14FE310 = 0x0000000000000000
0x000000AEC14FE30C = 0x0000000000000001

dumpobj 0x000001c0589e6a40
Name: DotnetDump.Controllers.HomeController
MethodTable: 00007ffc6bd80058
EEClass: 00007ffc6bd73968
Size: 104(0x68) bytes
File: E:\Test\DotnetDump\bin\Debug\netcoreapp3.1\DotnetDump.dll
Fields:
MT Field Offset Type VT Attr Value Name
00007ffc6bd9dd98 400005c 8 ...ControllerContext 0 instance 000001c0589e6508 _controllerContext
00007ffc6b9a69a8 400005d 10 ...lMetadataProvider 0 instance 0000000000000000 _metadataProvider
00007ffc6b9a8130 400005e 18 ...odelBinderFactory 0 instance 0000000000000000 _modelBinderFactory
00007ffc6b9a83e0 400005f 20 ...ectModelValidator 0 instance 0000000000000000 _objectValidator
00007ffc6bd9dea0 4000060 28 ...re.Mvc.IUrlHelper 0 instance 0000000000000000 _url
00007ffc6b9ae310 4000061 30 ...lemDetailsFactory 0 instance 0000000000000000 _problemDetailsFactory
00007ffc6bd9d0c8 400001e 38 ...empDataDictionary 0 instance 000001c0589e7100 _tempData
0000000000000000 400001f 40 ...s.DynamicViewData 0 instance 0000000000000000 _viewBag
00007ffc6bd9cf18 4000020 48 ...iewDataDictionary 0 instance 000001c0589e6ac8 _viewData
00007ffc6c052648 4000003 50 ...ler, DotnetDump]] 0 instance 000001c2189959c0 _logger
00007ffc6c05a3e8 4000004 58 ...Private.CoreLib]] 0 instance 000001c0589e6aa8 _byteBag
查看具体的变量信息dumpobj 内存地址。

第二种:分析内存泄漏

由于上面较为明显的看到内存问题,因此将代码改为,这种代码假设是无意中添加到一个静态变量_byteBag中。

使用命令:

安装上面的步骤收集转储文件后。进入分析

dumpheap -stat

可以使用参数 -max -min

再次获得所有实例列表

dumpheap -mt 00007ffc69712360

使用gcroot获得根

gcroot -all 000001c95d0b1038

gcroot -all 000001c95d0b1038

技术图片

没事不要写静态变量存储数据,依赖注入时代,可以使用单例代替。

使用dotnet-dump分析dotnet转储文件

标签:bytes col finalize class metadata 列表 meta apr queue

原文地址:https://www.cnblogs.com/yeqifeng2288/p/13910191.html

发表评论

0/200
0 点赞
0 评论
收藏
为你推荐 换一批