PerfView 概述:數組
PerfView是一個能夠幫助你分析CPU和內存問題的工具軟件。它很是輕量級也不會入侵診斷的程序,在診斷過程當中對診斷的程序影響甚微。dom
Visual Studio自帶的性能分析功能在CPU佔用、時間消耗、內存分配等方面的診斷效果還算不錯,但PerfView能夠提供更加豐富的診斷分析信息。工具
在這篇文章中,我將使用PerfView給你展示以下功能:性能
測試程序測試
如今咱們準備一個將會致使內存泄露的程序,用來確保使用PerfView能夠達到咱們所指望的效果。它是一個WinForm應用程序,後臺代碼以下:spa
public partial class Form1 : Form { private List<int[]> arrays = new List<int[]>(); Random random = new Random(); public Form1() { InitializeComponent(); Thread thread = new Thread(Start); thread.IsBackground = true; thread.Start(); } private void Start(object obj) { while (true) { int[] a = new int[random.Next(90000, 100000)]; arrays.Add(a); Thread.Sleep(10); } } }
使用PerfView進行跟蹤3d
開啓PerfView,你將會看到以下窗口:code
PerfView的使用手冊被集成在這個程序中,你能夠菜單欄來進行訪問。orm
而後點擊菜單「Collect-->Collect」來進行數據採集,用來分析生成診斷結果:對象
無需修改任何初始化配置,點擊「Start Collection」按鈕,PerfView將會開始採集全部進程的事件數據。
數十秒以後,你能夠點擊「Stop Collection」按鈕,PerfView將會中止採集並生成診斷文件「PerfViewData.etl.zip」:
獲取GC Stats
雙擊「GCStats」報表,將會彈出一個窗口,窗口中顯示了每個進程GC信息,找到咱們的測試程序。
關於測試程序咱們將會獲得以下彙總信息表:
進一步往下看,還會顯示GC觸發的緣由:
如上圖所示,此次GC的collection的發生是由於large object的分配。
獲取致使large object分配的緣由
從PerfView的主界面,雙擊打開「GC Heap Alloc Stacks」窗口,而後雙擊測試程序的進程,以後彈出的窗口將根據內存分配從大到小的次序顯示堆棧信息:
PerfView會將全部的large object分配都歸類在LargeObject節點下面,雙擊該節點能夠看到以下信息:
備註:若是你在上圖所示的界面中看到「OTHER<<clr?>>」,能夠對其鼠標右擊,而後點擊「Lookup Symbols」,來獲取CLR和Windows的功能名稱。
上圖中主要列的說明以下:
Inc%:表示該對象分配的字節佔全部記錄分配的百分比;
Inc:該對象分配字節的總數;
Inc Ct:該對象分配的次數。
從上圖能夠看出,巨多的large object都是來自Start方法的Int32數組,PerView精確地診斷出咱們預期的效果。
誰形成了內存泄露
PerfView能夠經過heap dump來查看佔用內存的對象的路徑。
從主界面點擊菜單項「Memory-->Tale Heap Snapshot」,彈出窗口以下圖所示:
找到咱們的測試程序並選中,而後點擊「Dump GC Heap」按鈕,數秒後再點擊「CLose」按鈕,最後會生成一個「.gcdump」文件。
雙擊打開「WindowsFormsApplication1.gcdump」窗口,顯示以下所示:
PrefView精確地診斷出,是static variables佔用了內存。
使用兩個Heap Dump來查看對象所佔內存的變化狀況
在應用程序連續運行的狀況下,對其進行兩次Take Heap Sanpshot,確保兩次生成的文件名稱不一致。同時打開這兩個.gcdump文件的窗口,經過任一一個窗口的diff菜單項功能,都能以另外一個窗口的數據爲基準進行對比。