CPU過高、死鎖、內存爆滿問題排查


一:CPU過高的問題

演示步驟:

  1. 生成release x64
  2. 在“任務管理器”中生成一個dump文件
  3. 需要用x64 的windbg。。。
  4. !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
  5. 切換到指定的線程 ~~[5ca8]s
  6.  查看當前線程的調用堆棧 !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() 方法之后就沒有調用堆棧了,說明方法在這個地方
    停滯不前了。

  7. 最后到指定的b__1_0方法去尋找一下是否有異常
  8. 通過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語句,或者“鎖機制”  導致死鎖

  1. ~*e!clrstack 查看所有線程的堆棧
  2. !threads 查看當前的托管線程
  3. syncblk 當前哪一個線程持有鎖

說先通過syncblk找到了持有鎖的線程,那么肯定有其他的線程在執行Monitor.Enter的時候進行不下去,也就是調用堆棧頂部到這個地方為止。

 

三:內存爆滿

  1. !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[]數組

  2. !DumpHeap /d -mt 00007ff932cc2860 //查看當前的方法表
  3. !DumpObj /d 00000135978d5340 //查看當前char[]的內容
  4. !gcroot 00000135a60f4940 //查看當前地址的Root

 調試圖書推薦:net高級調試


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM