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

來源:互聯網
上載者:User

標籤:

出處:
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-手錶) 來衡量各種點,根據需要來縮小熱路徑迭代添加秒錶之間運行所需的多長時間。
逐句通過代碼,看看如果任何特別是逐步執行”感覺慢”。
所有 (”暫停”) 按鈕在隨機點去感受如何遠的執行已取得進展的突破。在某些圈子裡這指作為”窮人的採樣”。
過度最佳化代碼沒有測量效能,有時通過在整個程式碼程式庫應用一套效能最佳做法。
這些做法通常是不準確的不是用時間或兩者都好。這就是為什麼現在有效能工具在調試器中。他們將協助您瞭解您的應用程式的效能,在正常調試過程中。

診斷工具視窗 您會注意到當 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。它從伺服器和每張圖片的縮圖中同步下載圖片的列表 (一次一個)。您可以通過取消您現有的斷點並將放在以下各行的新的時間這兩個操作:

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

重新啟動調試進程並等待,直到該應用程式命中第一個斷點處。然後讓應用程式能夠運行 (通過按 f5 鍵以繼續) 向第二個斷點。這允許應用程式從雲中檢索圖片的列表。然後讓應用程式運行到第二個斷點來衡量從雲端下載縮圖。PerfTips 和打破事件告訴您花了 565 女士得到的圖片列表和 6,426 的 ms 下載縮圖。效能瓶頸是在你下載的縮圖。

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

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

為了盡量減少等待用戶端和伺服器之間的往返時間,立即開始下載縮圖的所有操作,等待他們通過等待完成.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 方法調用。拍攝快照,通常會針對意外的記憶體使用量情況的下一步。在記憶體選項卡,單擊拍攝快照按鈕產生堆的快照。在斷點處或應用程式正在運行時,您可以拍攝快照。

如果您知道哪一行代碼導致尖峰記憶體使用量,然後你有一個想法在哪裡採取第一個快照。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--win32工程配置的一些想法之在 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.