1. 引入篇html
1.1 下載安裝
1.2 調試器
1.3 操做界面
2. 命令篇
2.1 按照來源劃分
2.1.1 基本命令
2.1.2 元命令
2.1.3 擴展命令
2.2 按照功能劃分
2.2.1 系統信息
2.2.2 進程
2.2.3 模塊
2.2.4 符號
2.2.5 線程
2.2.6 內存
2.2.7 事件
3. 探討篇
3.1方法內聯
3.2 字符串駐留池數據庫
記一次內存泄漏DUMP分析:http://www.cnblogs.com/LoveOfPrince/p/6032523.html數組
高CPU、數據庫沒法讀寫的真兇:http://www.javashuo.com/article/p-uqzuecca-mz.html瀏覽器
引入篇
1.1 下載安裝
1.2 調試器
1.3 操做界面服務器
所謂技術分享,實際上是一個自我總結和相互學習、不斷成長的過程。架構
考慮到以前原創的文章http://www.cnblogs.com/LoveOfPrince/p/6032523.html《記一次內存泄漏DUMP分析》被轉載,並且有的沒有說明出處,這裏全部的圖片都打了標記,很差意思啊。函數
WinDbg是微軟發佈的一款免費而十分強大的調試工具,從官網下載Microsoft Windows SDK,選擇安裝「Debugging Tools for Windows」。工具
安裝目錄下,有四個調試器程序。學習
cdb.exe和 ntsd.exe只支持用戶模式調試;Kd.exe主要用於內核調試,有時候也用於用戶模式。上述三者只能在控制檯界面以命令行形式工做。優化
Windbg.exe採用可視化的用戶界面,支持用戶模式和內核模式調試。在兩種模式下,都支持實時調試模式和過後調試模式。另外,還支持源碼級的調試。
命令篇
2.1 按照來源劃分
2.2 按照功能劃分
按照來源劃分
2.1.1 基本命令
2.1.2 元命令
2.1.3 擴展命令
用?查看基本命令
用.help查看元命令
用.chain查看擴展模塊,再查看指定模塊下的全部擴展命令
按照功能劃分
2.2.1 系統信息
2.2.2 進程
2.2.3 模塊
2.2.4 符號
2.2.5 線程
2.2.6 內存
2.2.7 事件
爲了下載和本地系統匹配的符號,可用以下命令查看本地系統信息。
這裏列出了操做系統版本、系統持續運行時間、調試時間等信息。
WinDbg可以同時調試多個進程。能夠直接附加已經存在的進程,也能夠建立新的進程並附加上去。 須要先切換到目標進程,檢查當前進程的環境信息,以確認是否切換成功。 最後,結束對當前進程的調試。
查看進程信息,以及包含的程序域。
模塊信息相關的命令。
列出了當前調試進程要加載的模塊符號信息,將指定模塊保存爲程序集,反編譯看看效果還不錯,不過有些變量名不是能直接看懂的。
好比查看模塊鏡像文件重定位信息,能夠發現基本上都是最優的。也能夠查看PE頭信息研究一下。
在建立二進制鏡像文件時,伴生的後綴名爲.dbg、.sym或.pdb的文件稱爲符號文件,包含以下符號信息:
1)源文件路徑以及每一個符號的行號。
2)變量的名字和地址。
3)函數名稱、地址及其原型。
4)幀指針優化數據。
5)變量、結構等的類型信息。
符號路徑用於告訴調試器去哪裏尋找符號文件,調試過程當中,只有正確設置了符號路徑,使得調試器可以將調試目標、符號文件以及源碼文件一一對應起來,纔可以最好地發揮調試器的強大功用。
若是涉及到成千上萬個符號文件,以及同一個符號文件存在不一樣平臺下的不一樣版本的時候,那麼一一手動設置符號路徑確定是不現實的,因而引入符號服務器的概念。符號服務器有一套命名規則,使得調試器可以正確找到對應平臺和版本的符號文件。
WinDbg訪問符號須要兩個文件(SYMSRV.DLL 和 SYMSTORE.EXE),須要設置系統變量告訴他這兩個文件放在什麼地方。
查看線程的基本信息。
好比列出全部(託管)線程。
線程號是由調試器軟件內部維護的線程ID值,是一個從0開始的整數,在外部是沒有太大意義的。
線程ID是系統維護的系統惟一的ID值。
線程的凍結狀態,決定了是否分發CPU時間給它。
查看線程的堆棧信息。
查看線程的時間信息,包括三個方面:自建立之初到如今的總消耗時間、用戶模式執行時間、內核模式執行時間。
除了耗時,還能夠查看線程池的信息。
內存是存儲數據、代碼的地方,經過內存查看命令能夠分析不少問題。經過查看堆上的大對象,以及對象的持有者,瞭解沒有被回收的緣由等。
經過查看堆上的大對象,以及對象的持有者,瞭解沒有被回收的緣由等。
Windbg是事件驅動的。
好比程序故障分析,電腦藍屏故障分析等。
查看C盤確實發現百度瀏覽器目錄,卸載百度殺毒、刪除C盤百度瀏覽器(也可清理下注冊表),重啓電腦,恢復正常。
探討篇
3.1方法內聯
3.2 字符串駐留池
默認狀況下,Release版本進行了各類優化,其中,將被調用方法的方法主體移入調用方的主體,就能夠避免某些方法的調用開銷,這一操做稱爲方法內聯。
能夠發現,DoCalc方法被內聯,而Calc方法卻不會。這裏提到一個問題,什麼是優秀的代碼,個人理解是除了讓人看的舒服,還要更貼近編譯優化後的代碼。
程序啓動時,系統域中的駐留池負責管理被駐留的字符串。抓取DUMP分析,查找這些字符串的根,發現都在一個object數組中,查看這個數組,果真是駐留池。
引用架構師修煉中的一段話:
發現問題永遠都比解決問題更加劇要。通常來講,從問題暴露的點,一點點去溯源查找,必定會找出來誰的問題,以及是什麼問題。最壞狀況就是當咱們時間或者能力有限,實在是沒法定位出是誰的問題的時候,好比系統出故障,也就意味着咱們沒法根本解決問題。這時最好的辦法就是去下降問題發生所帶來的成本,儘可能去隔離問題影響的範圍,留出時間和空間去識別真正的問題。