VS2015--win32project配置的一些想法之在 Visual Studio 2015 中進行調試的同一時候分析效能

來源:互聯網
上載者:User

標籤:保留   分享   額外   pretty   不同   nes   才幹   關係   win32   

出處:
https://msdn.microsoft.com/zh-cn/magazine/dn973013(en-us).aspx

很多開發商花了絕大多數時間擷取應用程式才幹正常發揮作用。更少的時間裡專註於應用程式的效能。

儘管有了非常長一段時間分析工具在 Visual Studio 中的,他們是單獨的一組學習工具。很多開發人員沒有花時間去學習和使用它們的時候會出現效能問題。

這篇文章將介紹 Visual Studio 2015 年新的診斷工具調試器表單。

它還將描寫敘述怎樣使用它來分析效能作為定期調試工作流程的一部分。

我會首先提供調試器的特性和功能的概述,然後對一個深潛演練。我會告訴你怎樣使用 PerfTips 來時間剖面的斷點和步驟之間的代碼、 怎樣使用診斷工具表單來監視 CPU 和記憶體,以及怎樣拍攝快照來鑽深進記憶體增長和泄漏。

這篇文章中的功能都可用於調試最託管和本機項目。

微軟不斷地加入很多其它的項目類型的支援、 調試配置。

有關當前受支援的功能的最新資訊,請查閱診斷工具表單在部落格的文章 aka.ms/diagtoolswindow。在這個問題上單獨的一條將解釋怎樣在診斷工具表單內使用 IntelliTrace (見”使用 IntelliTrace 對診斷問題更快,”) 來高速確定您的代碼中的 bug 的根源。

在調試時的效能
而不是執行一個完整的分析工具。你可能會採取一個或多個下面的步驟:

將代碼插入到應用程式 (比如 System.Diagnostics.Stop-手錶) 來衡量各種點,依據須要來縮小熱路徑迭代加入秒錶之間執行所需的多長時間。


逐句通過代碼。看看假設不論什麼特別是逐步執行”感覺慢”。
全部 (”暫停”) button在隨機點去感受怎樣遠的執行已取得進展的突破。

在某些圈子裡這指作為”窮人的採樣”。
過度最佳化代碼沒有測量效能,有時通過在整個程式碼程式庫應用一套效能最佳做法。
這些做法一般是不準確的不是用時間或兩者都好。

這就是為什麼如今有效能工具在調試器中。他們將協助您瞭解您的應用程式的效能,在正常調試過程中。

診斷工具表單 您會注意到當 Visual Studio 2015 年調試代碼的新的診斷工具表單中將會出現。如中所看到的的主要區別在於 圖 1。這些診斷工具在兩個相互補充的方式呈現資訊。他們將圖形加入到時間軸中表單的上半。並提供具體的資訊選項卡中的底部。



圖 1 在 Visual Studio 2015 年新的診斷工具表單

在 Visual Studio 到 2015 年,您將看到在診斷工具表單中的三個工具:調試器 (包含 IntelliTrace)、 記憶體和 CPU 使用率。

您能夠啟用或禁用的 CPU 使用率和記憶體使用量的工具,通過點擊選擇工具下拉式清單。調試器工具已表明打破事件、 輸出事件和 IntelliTrace 事件的三個軌道。

打破曆史上重大事件和 PerfTips 打破事件讓你看到每一節代碼花多長時間執行。

矩形代表從應用程式開始或恢複執行,直至調試器作出它暫停時的期間 (見圖 2)。



圖 2 斷裂事件和 PerfTips

矩形的起點指示你從哪裡開始通過繼續步進 Shift + F11 F11 F10) 或執行到游標處 (Ctrl + F10) 命令 (F5),執行應用程式。結束了該矩形指示由於它命中了斷點,完畢一個步驟或由於您使用了打破全部應用程式停止的位置。

最新的中斷事件的期間也顯示在調試器中的當前行末尾處的代碼。

這被稱為 PerfTips。它同意您監視效能沒有考慮你的眼睛離開你的代碼。

在關係圖下方的細節表中。也能夠看到曆史和打破事件和 PerfTips 表格格式的期間。假設你有 IntelliTrace,附加事件將顯示在表中。您還能夠使用篩選器顯示僅僅有調試器來查看僅僅有打破事件的記錄。

CPU 和記憶體分析時間軸自己主動選擇時間範圍內,如您設定斷點並單步。

當遇到斷點時,目前時間範圍被重設。僅僅將最新的中斷事件顯示。

所選內容能夠擴大到包含最新的中斷事件。通過點擊一個打破事件矩形或通過單擊並拖動時間軸上。您能夠覆蓋自己主動時間範圍選擇。

時間範圍選擇同意您關聯範圍上的 CPU 使用率和記憶體使用量情況圖。以便您能夠理解代碼的特定部分的 CPU 和記憶體的特點。

圖繼續更新在該應用程式執行時,讓你幫我照看對 CPU 和記憶體作為您與您的應用程式進行互動。您能夠切換到記憶體選項卡。拍攝快照並查看記憶體使用量情況的具體分項數字。

IntelliTrace 效能洞察力 IntelliTrace (在 Visual Studio 社區版本號碼中不可用) 讓你獲得很多其它的洞察效能調試託管的代碼時。

IntelliTrace 向偵錯工具事件時間軸中加入兩個軌道:輸出跟蹤和 IntelliTrace 軌道。這些事件包含資訊顯示在輸出表單中。再加上額外的事件收集的 IntelliTrace,如異常,ADO.NET,等等。在這些軌道發生的事件也是偵錯工具事件表所看到的。

你能夠涉及的 IntelliTrace 事件穗狀花序的 CPU 使用率和記憶體使用量情況圖。時間戳記顯示你多久各種行動在您的應用程式。比如,您能夠在您的代碼中加入 Debug.WriteLine 語句,使用時間戳上輸出事件查看從一個語句到下一個執行所須要的多長時間。

提高效能和記憶體
如今。您已經看到該表單的功能。我們將深入探討實際用途的工具。在本節中。我們步行通過求解一組稱為照片濾鏡的例子應用程式中的效能問題。這個應用程式將從雲端下載圖片和從使用者的本地圖片庫載入圖片,這樣他能夠查看它們。並應用映像篩選器。

假設你想要跟著,下載源碼從 aka.ms/diagtoolswndsample。由於效能是不同的不同的機器上。你會發現不同的數字。

它甚至會有所不同從執行。

慢啟動應用程式當您開始調試照片濾鏡應用程式時,你會發現它須要非常長的時間,要啟動應用程式和載入的圖片。

這是一個明顯的問題。

當您在調試應用程式的功能性問題時,你往往形成一個假設並開始調試在此基礎。在這樣的情況下,你能猜測圖片是緩慢載入。並尋找一個好的地方設定一個斷點,並考驗一下這個假說。

LoadImages 方法是一個偉大的地方,做到這一點。

開始和結束時的 LoadImages 函數設定斷點 (所看到的的代碼中圖 3) 和開始調試 (F5)。

當代碼命中第一個斷點處時,按繼續 (F5) 再次跑到第二個斷點。

如今有兩個斷裂事件在時間軸中偵錯工具事件。



圖 3 LoadImages 方法

第一步顯示應用程式執行僅 274 毫秒之前命中第一個斷點。第二部分示範了 10,476 女士要打第二個斷點之前在 LoadImages 函數中執行此代碼。您還能夠看到經過時間 PerfTip 在代碼中顯示同樣的值。所以你已經縮小到 LoadImages 函數問題。

若要擷取很多其它的資訊和每一行須要多久的時間,又一次啟動調試所以你再打第一個斷點。這一次,逐句通過每一行代碼中方法以查看哪些行正在最長的時間。

從 PerfTips 和調試中斷事件的期間,你能夠看到 GetImagesFromCloud 花 7,290 女士、 LoadImagesFromDisk 須要 736 女士、 LINQ 查詢所需 1,322 女士和其餘在小於 50 毫秒內完畢。

對於全部行時機所看到的圖 4。

行號顯示代表大課間活動,末尾處的線,所以線 52 意味著多長時間它接管了步線 51。 如今鑽進一步入 GetImagesFromCloud 方法。



圖 4 偵錯工具事件表的每一個步驟顯示經過的時間

GetImagesFromCloud 方法執行兩個獨立的邏輯操作,如中所看到的圖 5。它從server和每張圖片的縮圖中同步下載圖片的列表 (一次一個)。

您能夠通過取消您現有的斷點並將放在下面各行的新的時間這兩個操作:

圖 5 改進了代碼 () 與 GetImagesFromCloud 方法 (頂部)

又一次啟動調試進程並等待,直到該應用程式命中第一個斷點處。然後讓應用程式能夠執行 (通過按 f5 鍵以繼續) 向第二個斷點。這同意應用程式從雲中檢索圖片的列表。

然後讓應用程式執行到第二個斷點來衡量從雲端下載縮圖。PerfTips 和打破事件告訴您花了 565 女士得到的圖片列表和 6,426 的 ms 下載縮圖。

效能瓶頸是在你下載的縮圖。

當你看著 CPU 使用率圖 (所看到的圖 6),該方法檢索的映像列表。你能夠看到它是相對較高。圖形是相當平坦時表明這一過程花了非常長一段時間,等待網路 I/O 的縮圖下載。



圖 6 CPU 使用率圖指示延遲網路輸入/輸出

為了盡量減少等待client和server之間的往返時間,馬上開始下載縮圖的全部操作。等待他們通過等待完畢.NET System.Tasks 來完畢。

代替第 73 至 79 行 (從代碼中圖 5) 用下面的代碼:

// Download thumbnailsvar downloadTasks = new List<Task>();foreach (var image in pictureList){  string fileName = image.Thumbnail;  string imageUrl = ServerUrl + "/Images/" + fileName;  downloadTasks.Add(DownloadImageAsync(new Uri(imageUrl), folder, fileName));}await Task.WhenAll(downloadTasks);

當你的時候這個新的版本號碼時,你能夠看到須要僅僅有 2,424 女士來執行。這是關於四秒的改進。

調試記憶體增長和泄漏假設你看看記憶體使用量情況圖診斷慢啟動時,您可能已經注意到記憶體使用量量的急劇添加為啟動該應用程式。縮圖的列表是虛擬化的列表,而僅僅有一個全然尺寸的映像顯示在一段時間。

使用虛擬化的列表的長處之中的一個是它僅載入內容顯示在螢幕上,所以你不會期望非常多縮圖在記憶體中一次。

要到這一問題的根本原因,你必須找到在代碼中記憶體增長出現。然後。拍取快照之前和之後的增長。

比較這些快照。你會發現最有助於生長在記憶體中的物件類型。

記憶體使用量情況圖顯示了應用程式怎樣使用記憶體的進階視圖。還有計數器命名專用位元組數為您的應用程式的效能。專用位元組數是記憶體的衡量的分配給進程總量。這還不包含與其它進程共用的記憶體。它包含託管的堆、 本機堆、 線程堆棧和其它記憶體 (如載入的.DLL 檔案的私人部門)。

當開發一個新的應用程式或診斷問題與現有的一個,意外的增長的記憶體使用量情況圖上會常常是你已經不表現如預期的代碼的第一個跡象。

看圖,您能夠使用調試器功能如斷點和逐步執行來縮小感興趣的代碼路徑。你能夠從行號和期間顯示在偵錯工具事件選項卡又一次確定圖 4負責意外增長線是線 52。LoadImagesFromDisk 方法調用。

拍攝快照,一般會針對意外的記憶體使用量情況的下一步。

在記憶體選項卡,單擊拍攝快照button產生堆的快照。在斷點處或應用程式正在執行時。您能夠拍攝快照。

假設您知道哪一行代碼導致尖峰記憶體使用量。然後你有一個想法在哪裡採取第一個快照。LoadImagesFromDisk 方法上設定斷點和拍攝快照,當您的代碼到達該斷點。此快照作為基準。

接下來,逐步執行的 LoadImagesFromDisk 方法,並產生還有一個快照。如今,通過比較快照,你將能夠看到哪些託管的類型已加入到你跨過為函數調用的結果堆。圖再一次顯示了記憶體利用率穗正在調查 (如中所看到的圖 7)。您還能夠看到通過滑鼠移至上方圖形記憶體 47.4 MB。

它是一個好的主意來心理記數MB。所以您能夠稍後驗證您修複了有意義的影響。

有是記憶體使用量量明顯激增

圖 7 有是記憶體使用量量明顯激增

具體資訊視圖顯示每一個快照的簡要的概述。概述包含快照的順序號,執行的時間 (以秒為單位) 時拍攝快照。堆的大小和數量的活堆上的對象。興許快照也會顯示變化的大小和對象計數從曾經的快照。

拍攝快照的過程列舉了僅僅有那些仍然生活在堆上的對象。也就是說,假設對象是符合記憶體回收條件。不會包含在快照中。

這樣的方式。你不須要操心當集合最後跑了。每一個快照中的資料是。彷彿剛剛發生記憶體回收。

顯示快照概述在堆的大小將低於專用位元組記憶體使用量情況圖表中顯示。專用位元組數概要顯示全部類型的由您的進程分配的記憶體。而快照顯示的大小全部活對象在託管堆上。假設你看到在記憶體使用量情況圖中。大量添加,但增長託管堆中的並不佔多數的它,生長在記憶體中其它地方發生。

從快照概述中,您能夠開啟堆視圖並調查按類型堆的內容。單擊第二個快照,在新選項卡中開啟堆視圖的對象 (差異) 列中 diff 連結。單擊該連結將排序堆視圖中的類型由自曾經的快照建立的新對象的數目。這讓你感興趣頂部的表的類型。

堆視圖快照 (見圖 8) 有兩個主要部分:頂部窗格和下部窗格中引用圖中的物件類型表。物件類型表顯示的名稱、 數量和大小的每一個物件類型時拍攝快照。

中 Diff 模式的堆視圖快照

圖 8 中 Diff 模式的堆視圖快照

幾個在堆檢視類型是從架構。

假設你有Just My Code啟用 (預設值)。這些都是在您的代碼中參考型別或由您的代碼類型引用的類型。使用此視圖,您能夠識別一個類型從我們靠近頂部的 table—PhotoFilter.ImageItem 的代碼。

在圖 8。你能夠看到計數 Diff 列顯示自曾經的快照建立的 137 新映像對象。頂五個新物件類型都有同樣數量的新的對象,所以這些可能相關。

讓我們看看第二個窗格。參考圖。假設你期望要清理記憶體回收行程的類型,但它仍顯示在類型表中,根的路徑能夠協助您跟蹤下什麼持有該引用。

到根的路徑是參考圖中這兩種視圖之中的一個。到根的路徑是自底向上樹顯示完整的圖形類型生根您所選的類型。假設還有一個應用程式物件儲存了一個引用,植根的對象。

不必要的根的對象往往是在Managed 程式碼中記憶體泄露的原因。

引用的類型,還有一個視圖。則相反。

為在物件類型表中,選擇此視圖顯示其它類型的類型引用了您選定的類型。此資訊能夠有助於確定為什麼在很多其它的記憶體比預期堅持所選類型的對象。這是實用的現狀調查。由於類型可能會使用很多其它的記憶體比預期。但他們並不比它們的用處。

在物件類型表中選擇 PhotoFilter.ImageItem 行。參考圖將更新以顯示關係圖的映像。在參考型別視圖中。您能夠看到映像對象保留共 280 的字串對象和 140 每一個架構的三種類型:StorageFile、 StorageItemThumbnail 和 BitmapImage。

總大小使它看起來好像貢獻由映像對象保留的記憶體的添加最大字串對象。專註於總大小 Diff 列使非常有意義,但數目不會導致的根本原因。

一些架構類型,如 BitmapImage,僅僅有極少量的舉行在託管堆上的記憶體總量。

BitmapImage 執行個體的數量是一個更令人信服的線索。記得在照片濾鏡的縮圖的列表虛擬所以它應該載入這些映像上的需求,並使其可作為記憶體回收。當它做。然而,看起來好像提前載入全部縮圖。結合你如今瞭解什麼 BitmapImage 對象被冰山,繼續專註於那些進行調查。

PhotoFilter.ImageItem 在參考圖中。右擊並選擇轉到定義映像在編輯器中開啟源檔案。

映像定義的成員欄位,m_photo,即 BitmapImage,如中所看到的圖 9。

代碼引用 m_photo 的成員欄位

圖 9 代碼引用 m_photo 的成員欄位

第一個代碼路徑引用 m_photo 是屬性的 get 方法的照片,它是屬性的資料繫結到 ListView 在 UI 中的縮圖。它看起來像 BitmapImage 正在載入 (和因此解碼在本機堆上) 上的需求。

引用 m_photo 的第二個代碼路徑是 LoadImageFromDisk 的功能。這個項目是相應用程式的啟動路徑。

應用程式啟動時,它擷取呼籲被顯示,每一個映像。

這有效地預載入 BitmapImage 的全部對象。這樣的行為不利於虛擬列表視圖中,作為已指派的全部記憶體,不管列表視圖中顯示映像的縮圖。該預載入演算法不能非常好地擴充。很多其它的圖片,你有在你的圖片庫中。啟動記憶體成本也就越高。

按需載入 BitmapImage 對象是更具可擴充性的解決方式。

後停止調試器。請凝視掉線 81 和 82 在 LoadImageFromDisk 載入 BitmapImage 執行個體。為驗證您已經固定記憶體效能問題而不會破壞應用程式的功能。然後又一次執行同樣的實驗。

按 F5,你就會看到總記憶體使用量量是如今僅僅有 26.7 MB (見圖 10)。

以還有一組的快照之前、 之後調用 LoadImagesFromDisk,然後比較他們。你會看到仍然是 137 的映像對象,但沒有 BitmapImages (見圖 11)。BitmapImages 將載入需求上,一旦你讓應用程式繼續啟動。

記憶體配置圖在固定的引用問題

圖 10 記憶體配置圖在固定的引用問題

參考圖後固定記憶體的問題

圖 11 參考圖後固定記憶體的問題

正如前面提到的此調試器整合的工具還支援拍照的本機堆或託管和本機堆同一時候。堆你設定檔為基礎上的調試器,您正在使用:

僅託管調試器僅僅需託管堆的快照。
僅限原生偵錯工具 (本機項目的預設值) 僅僅須要本機堆快照。
混合模式調試器須要的託管和本機堆快照。
您能夠調整此設定對您的項目屬性的調試頁。

當不啟用調試執行工具
它是重要的是提及須要額外開銷介紹了當您測量與調試器的效能。主類的開銷來自您通常執行的應用程式的調試版本號碼的事實。

您公布到使用者的應用程式將公布版本號碼。

在調試版本號碼中。編譯器保持了儘可能接近原始的源碼作為可能的結構和行為的可執行檔。正如您期望在調試時,一切應該工作。還有一方面。公布版本號碼試圖最佳化代碼的效能減少的調試體驗的方式。一些例子包含襯砌中的函數調用和常數變數,移除未使用的變數和代碼路徑和儲存變數資訊可能無法讀取由調試器的方式。

全部這一切意味著 CPU 密集型代碼能夠有時執行速度顯著變慢在調試版本號碼中。非 CPU 密集型的操作。如磁碟 I/O 和網路調用將採取同樣多的時間。通常不是記憶行為,意味著泄漏的記憶體會泄露和低效的記憶體的使用仍將顯示作為大量添加這兩種情況區別非常大。

它附加到目標應用程式時,將由調試器加入其它開銷的類來考慮。調試器截獲模組載入和異常的事件。它也提供其它所需的工作讓你設定斷點和步驟。

Visual Studio 會儘力篩選這樣的類型的開銷從效能的工具,但仍有少量的開銷。

假設你看到一個應用程式的公布版本號碼中的一個問題。它將差點兒總是複製在調試版本號碼中,但不是一定在附近的其它方式。為此,調試器整合工具旨在協助您在開發過程中主動地發現效能問題。假設您在調試版本號碼中發現的問題,你能夠翻到公布版本號碼。看假設這一問題影響以及公布版本號碼。

可是,您可能決定往前走並在調試版本號碼中解決該問題,假設你決定這是預防效能良好的工作 (也就是說,修複問題減少以後遇到效能問題的機會)。假設您確定問題是非 CPU 密集型 (磁碟或網路 I/O),或假設您想要加快調試版本號碼,所以在開發過程中,您的應用程式是迅捷。

報告效能問題時在公布版本號碼中,您想要確保您能夠複製和驗證你已經攻克了問題。最好的辦法做到這一點是翻轉您為公布模式的產生與所報告的問題相符的環境中執行的工具不使用調試器。

假設你想測量業務期間,調試器--整合的工具將僅僅能精確到內幾十毫秒量較少的系統開銷。

假設你須要更高一級。執行不用調試器工具是準確性的一個更好的選擇。

總結
你能夠通過下載 Visual Studio 2015 RC 嘗試視覺工作室 2015 年新的診斷工具調試器表單。使用這些新的整合調試工具能夠協助您提高效能,您在調試您的應用程式。

VS2015--win32project配置的一些想法之在 Visual Studio 2015 中進行調試的同一時候分析效能

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.