CPU过高、死锁、内存爆满问题排查
一:CPU过高的问题
演示步骤:
- 生成release x64
- 在“任务管理器”中生成一个dump文件
- 需要用x64 的windbg。。。
- !runaway 查看当前托管线程已执行时间
Thread Time
9:5ca8 0 days 0:00:37.796
0:2a68 0 days 0:00:00.015
8:5600 0 days 0:00:00.000
7:46fc 0 days 0:00:00.000
6:33d4 0 days 0:00:00.000
5:3498 0 days 0:00:00.000
4:5644 0 days 0:00:00.000
3:398 0 days 0:00:00.000
2:2a60 0 days 0:00:00.000
1:63c0 0 days 0:00:00.000 - 切换到指定的线程 ~~[5ca8]s
- 查看当前线程的调用堆栈 !clrstack
000000f4d63ff2a8 00007ff8d50405f7 *** WARNING: Unable to verify checksum for ConsoleApplication51.exe
ConsoleApplication51.Program+c.b__1_0() [c:\users\hxc\documents\visual studio 2015\Projects\ConsoleApplication51\ConsoleApplication51\Program.cs @ 22]
000000f4d63ff2b0 00007ff932b10937 System.Threading.Tasks.Task.Execute()
000000f4d63ff2f0 00007ff932ac674e System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
000000f4d63ff3c0 00007ff932ac65e7 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
000000f4d63ff3f0 00007ff932b10bdd System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef)
000000f4d63ff4a0 00007ff932b10303 System.Threading.Tasks.Task.ExecuteEntry(Boolean)
000000f4d63ff4e0 00007ff932acfa10 System.Threading.ThreadPoolWorkQueue.Dispatch()
000000f4d63ff978 00007ff934626a53 [DebuggerU2MCatchHandlerFrame: 000000f4d63ff978]从调用堆栈上来看,当前线程 在 Program+c.b__1_0() 方法之后就没有调用堆栈了,说明方法在这个地方
停滞不前了。 - 最后到指定的b__1_0方法去寻找一下是否有异常
- 通过windbg自己生成dll 【!help】
!dumpdomain
!savemodule 00007ff8d4f350f0 c:\2\1.dll
class Program { static void Main(string[] args) { Run(); Console.Read(); } static void Run() { var task = Task.Factory.StartNew(() => { var i = true; //这个地方是一个非常复杂的逻辑。导致死循环 while (true) { i = !i; } }); } }
二:死锁问题
乱用lock语句,或者“锁机制” 导致死锁
- ~*e!clrstack 查看所有线程的堆栈
- !threads 查看当前的托管线程
- syncblk 当前哪一个线程持有锁
说先通过syncblk找到了持有锁的线程,那么肯定有其他的线程在执行Monitor.Enter的时候进行不下去,也就是调用堆栈顶部到这个地方为止。
三:内存爆满
- !dumpheap -stat 查看clr的托管堆中的各个类型的占用情况
00007ff932cc2aa8 19 1296 System.String[]
00007ff932cc3698 58 3248 System.RuntimeType
00007ff932cc16b8 186 9218 System.String
000001358b1503d0 57 12824 Free
00007ff932cc1d30 6 35216 System.Object[]
00007ff932cc5dc0 13762 660576 System.Text.StringBuilder
00007ff932cc2860 13775 220334298 System.Char[]然后看到了有13775个char[]数组
- !DumpHeap /d -mt 00007ff932cc2860 //查看当前的方法表
- !DumpObj /d 00000135978d5340 //查看当前char[]的内容
- !gcroot 00000135a60f4940 //查看当前地址的Root
调试图书推荐:net高级调试