在 Visual Studio 中測量記憶體使用量(C#、Visual Basic、C++、F#)
當您使用整合在調試程式中的 記憶體使用量 診斷工具進行偵錯時,尋找記憶體流失和低效能的記憶體。 記憶體使用量工具可讓您擷取一或多個 快照, 受控和原生記憶體堆,以協助了解物件類型的記憶體使用量影響。 您也可以分析記憶體使用量,而不附加調試程式,或以執行中的應用程式為目標。 如需詳細資訊,請參閱 在發佈版或偵錯版中執行分析工具。 如需為您的需求選擇最佳記憶體分析工具的資訊,請參閱 選擇記憶體分析工具。
雖然您可以隨時在 記憶體使用量 工具中收集記憶體快照集,但您可以使用Visual Studio調試程式來控制應用程式在調查效能問題時的執行方式。 設定斷點、逐步執行、全部暫停和其他偵錯動作,可協助您將效能調查聚焦於最相關的程式碼路徑上。 當您的應用程式正在執行時執行這些動作,可以消除您不感興趣的程式代碼雜訊,並大幅減少診斷問題所需的時間。
重要
Visual Studio 中的 .NET 開發支援調試器整合診斷工具,適用於 ASP.NET、ASP.NET Core、原生/C++開發,以及混合模式(.NET 和原生)應用程式。
在本教學課程中,您將:
- 擷取記憶體快照
- 分析記憶體使用量數據
如果 記憶體使用量 未提供您需要的數據,Performance Profiler 中的其他分析工具 提供可能對您有説明的不同類型資訊。 在許多情況下,應用程式的效能瓶頸可能是記憶體以外的部分所造成,例如 CPU、轉譯 UI 或網路要求時間。
注意
自訂記憶體分配器支援 原生記憶體分析工具透過收集運行期間發出的 ETW 事件數據來運作。 CRT 和 Windows SDK 中的配置器已在來源層級加上批注,以便擷取其配置數據。 如果您要撰寫自己的配置器,則任何傳回新配置堆記憶體指標的函式都可以加上 __declspec(allocator) 的裝飾,如 myMalloc 的範例所示:
__declspec(allocator) void* myMalloc(size_t size)
收集記憶體使用量數據
開啟您想要在 Visual Studio 中偵錯的專案,並在您想要開始檢查記憶體使用量的點,在應用程式中設定斷點。
如果您有懷疑記憶體問題的區域,請在發生記憶體問題之前設定第一個斷點。
提示
由於您的應用程式經常分配和釋放記憶體,這可能導致您難以擷取感興趣之作業的記憶體剖析,因此請在作業的開頭和結尾設定斷點(或逐步檢查作業),以找出記憶體變更的確切點。
在您想要分析之函式或程式代碼區域的結尾設定第二個斷點(或在發生可疑的記憶體問題之後)。
除非您已關閉診斷工具,否則 診斷工具 視窗會自動顯示。 若要再次顯示視窗,請按下 [偵錯]>Windows>[顯示診斷工具]。
使用工具列上的 [選取工具] 設定,選擇 [
記憶體使用量] 。 按兩下工具列上的 偵錯/開始偵錯(或 開始,或 F5)。
當應用程式完成載入時,[診斷工具] 的 [摘要] 檢視隨即出現。
注意
由於收集記憶體資料可能會影響原生或混合模式應用程式的偵錯效能,因此預設會停用記憶體快照集。 若要在原生或混合模式應用程式中啟用快照集,請啟動偵錯會話(快捷鍵:F5)。 當 [診斷工具] 視窗出現時,請選擇 [記憶體使用量] 索引標籤,然後選擇 [堆積分析]。
停止 (快捷鍵:Shift+F5),然後重新啟動偵錯。
注意
由於收集記憶體資料可能會影響原生或混合模式應用程式的偵錯效能,因此預設會停用記憶體快照集。 若要在原生或混合模式應用程式中啟用快照集,請啟動偵錯會話(快捷鍵:F5)。 當 [診斷工具] 視窗出現時,請選擇 [記憶體使用量] 索引標籤,然後選擇 [堆積分析]。
停止 (快捷鍵:Shift+F5),然後重新啟動偵錯。
若要在偵錯會話開始時擷取快照集,請選擇 [記憶體使用量] 摘要工具欄上的 [擷取快照集]。 (也可以在這裡設定斷點,這可能會有所幫助。)
提示
若要建立記憶體比較的基準,請考慮在偵錯會話開始時拍攝快照。
執行會觸發第一個斷點的場景。
當調試程式在第一個斷點暫停時,請選擇 [記憶體使用量] 摘要工具列上的 [擷取快照集]。
按 F5,將應用程式執行到您的第二個斷點。
現在,擷取另外一個快照。
此時,您可以開始分析數據。
如果您無法收集或顯示數據,請參閱 針對分析錯誤進行疑難解答,並修正的問題。
分析記憶體使用量數據
記憶體使用量摘要數據表的數據列會列出您在偵錯會話期間所擷取的快照集,並提供更詳細檢視的連結。
數據行的名稱取決於您在專案屬性中選擇的偵錯模式:.NET、原生或混合(.NET 和原生)。
Objects(Diff)(.NET)或 Allocations(Diff)(C++)欄位顯示在擷取快照當下 .NET 或原生記憶體中的物件數量。
堆大小(差異) 欄位顯示 .NET 和原生堆中的位元組數目
當您擷取多個快照時,摘要表的單元格會包含該列快照與之前快照之間的值變更。
若要分析記憶體使用量,請按兩下其中一個連結,以開啟記憶體使用量的詳細報告:
- 若要檢視目前快照集與上一個快照集之間差異的詳細數據,請選擇箭號左邊的變更連結()。 紅色箭號表示記憶體使用量增加,而綠色箭號表示減少。
提示
為了協助更快速地識別記憶體問題,差異報告會依整體數目增加最多的物件類型(按一下 [物件(差異)] 欄中的變更連結)或依整體堆大小增加最多的物件類型(按一下 [堆大小(差異)] 欄中的變更連結)進行排序。
若要只檢視所選快照集的詳細數據,請按下非變更連結。
報表會出現在不同的視窗中。
管理型別報告
在 [記憶體使用量] 摘要表中,選擇 物件 (Diff) 儲存格的目前連結。
注意
針對 .NET 程式代碼,
頂端窗格將顯示快照中各類型的數量和大小,包括該類型所引用所有物件的大小(包含大小)。
在底部窗格中,[指向根的路徑] 樹形結構會顯示參考上方窗格所選類型的物件。 .NET 垃圾收集器只有當對象的最後一個參考被釋放時,才會清理該對象的記憶體。 如需有關使用 根目錄路徑 樹的詳細資訊,請參閱 分析熱門路徑至根目錄。
頂端窗格將顯示快照中各類型的數量和大小,包括該類型所引用所有物件的大小(包含大小)。
在底部窗格中,[指向根的路徑] 樹形結構會顯示參考上方窗格所選類型的物件。 .NET 垃圾收集器只有當對象的最後一個參考被釋放時,才會清理該對象的記憶體。
參照型別的 樹狀視圖會顯示在上方窗格中所選擇的類型所持有的參照。
參照型別的 樹狀視圖會顯示在上方窗格中所選擇的類型所持有的參照。
若要在上方窗格中顯示所選類型的實例,請按兩下物件類型旁的 [檢視實例] 圖示
實例 視圖會在上方窗格的快照中顯示所選取物件的實例。 根目錄的 路徑窗格會顯示參考所選實例的物件 以及所選實例所參考的類型 參考物件。 當調試程式在擷取快照集的點停止時,您可以將滑鼠停留在 Value 單元格上,以在工具提示中顯示物件的值。
實例 視圖會在上方窗格的快照中顯示所選取物件的實例。 根目錄的 路徑窗格會顯示參考所選實例的物件 以及所選實例所參考的類型 參考物件。 當調試程式在擷取快照集的點停止時,您可以將滑鼠停留在 Value 單元格上,以在工具提示中顯示物件的值。
原生類型報表
在 [診斷工具] 視窗的 [記憶體使用量] 摘要表中,選擇 配置(Diff) 或 堆積大小(Diff) 單元格的當前連結。
類型檢視 會顯示快照中類型的數目和大小。
選擇實例圖示 (),以顯示快照中所選類型物件的相關信息。
實例 檢視會顯示所選類型的每個實例。 選取實例會顯示在 [配置呼叫堆疊] 窗格中創建該實例的呼叫堆疊。
在 [檢視模式] 清單中,選擇 [堆棧檢視],以查看所選類型的配置堆棧。
記憶體使用量深入解析
針對受控記憶體,記憶體分析工具還提供多項功能強大的內建自動分析。 在「受控類型」報告中選取「Insights」索引標籤,並會顯示適用的自動深入分析,例如 重複字串、稀疏陣列,以及 事件處理常式洩漏。
重複字串 區段會顯示在堆上多次分配的字串清單。 此外,本節會顯示浪費的總記憶體,也就是字串大小的 (實例數目 - 1) 倍。
稀疏陣列 區段顯示大部分元素為零的陣列,這在效能和記憶體使用方面可能效率不佳。 記憶體分析工具會自動偵測這些陣列,並告訴您由於這些零值,這些陣列有多少記憶體被浪費了。
Visual Studio 2022 版本 17.9 Preview 1 中提供的 事件處理器洩漏 區段會顯示某個物件訂閱另一個物件事件時可能發生的記憶體洩漏。 如果事件的發行者比訂閱者存活更久,則即便沒有其他參考,訂閱者仍然會繼續存在。 這可能會導致記憶體流失,其中未使用的記憶體未正確釋放,導致應用程式在一段時間內使用越來越多的記憶體。
已知某些類型具有可讀取的欄位,以判斷其所持有的原生記憶體大小。 [Insights] 索引卷標會顯示物件圖形中的假原生記憶體節點,這些節點會由其父物件保留,讓 UI 能夠辨識它們並顯示其大小和參考圖表。
變更 (差異) 報告
在 [
診斷工具] ] 視窗的 [記憶體使用量] 索引卷標的 [記憶體使用量] 索引卷標的單元格中,選擇變更連結。 在受管理或原生報表的 比較到 清單中,選擇一個快照。
變更報表會將數據行 (標示為 (Diff)) 新增至基底報表,以顯示基底快照集值與比較快照集之間的差異。 原生類型檢視差異報表可能是這樣:
頂端窗格將顯示快照中各類型的數量和大小,包括該類型所引用所有物件的大小(包含大小)。
部落格和影片
Visual C++ 部落格:Visual C++ 2015 中的記憶體分析
後續步驟
在本教學課程中,您已瞭解如何收集和分析記憶體使用量數據。 如果您已完成分析工具的
在本教學課程中,您已瞭解如何在偵錯時收集和分析記憶體使用量數據。 您可能想要深入瞭解如何使用效能分析工具來分析發行組建中的記憶體使用量。