Windows中有一個很強大的內置工具,稱為性能監視器(Performance Counters),可讓您跟蹤很多有用的性能指標。它是免費的,且容易上手使用,但是很多人沒有很好地使用它。
這是使用性能監視器可以監視的部分內容:
- CPU使用率
- 內存使用情況
- 進程中引發的異常數
- ASP.NET應用程序中的請求數
- 在ASP.NET應用程序中請求響應時間
通過它你能監視數百種具體不同的計數器。例如,假如想了解進程的內存使用情況,它提供了專用字節,虛擬字節,工作集合,工作私有集合,Gen X集合,GC中的時間百分比,大對象堆大小以及其他更多計數器。
在本文中,我們將看到如何使用PerfMon監視性能計數器,最有價值的計數器以及如何在代碼中編寫自己的自定義計數器。
在PerfMon中使用性能計數器
在Windows中監視性能計數器的主要工具是Performance Monitor(或稱PerfMon)。這個工具已經在Windows中,可以在開始菜單中鍵入“PerfMon”或在命令行窗口中運行“ perfmon”命令來找到它。
要實時查看性能計數器,請單擊左側菜單中的性能監視器。您可能會看到一個默認計數器%Processor Time已經存在。要添加更多計數器,請單擊“ +”圖標。
在出現的對話框中,您將看到類別,計數器和實例三個部分。每個類別包含許多計數器。每個計數器可以包含多個實例,這些實例允許更詳細地監視該計數器。
在上圖中,在實例實例AzureStorageEmulator的所有堆中添加了#字節計數器。與許多其他計數器一樣,在此計數器中,實例是進程。這意味着計數器將僅監測“ AzureStorageEmulator”進程的字節。
添加后,新計數器將出現在圖形中。您可以更改顏色,比例,線條樣式和其他屬性。
您可以將監視器會話保存到文件中。為此,首先添加任何你要記錄的計數器。然后,右鍵單擊左側菜單中的“性能監視器”項目,然后選擇“新建| 數據收集器集,輸入適當的名稱並選擇日志目錄。
新集合將出現在左側菜單 “數據收集器集” |“用戶定義“菜單項中。如果要開始錄制,請右鍵單擊收集器集,然后選擇開始。要停止,請右鍵單擊並選擇停止。它將會創建一個.blg后綴的文件,以后可以在PerfMon中打開該文件。
有價值的調試計數器
每種故障排除類型都有不同的重要計數器。掛起狀態的應用程序,和性能較慢的情況,我們將檢查不同的事項。同時ASP.NET也具有自己的一組計數器。
重要的CPU計數器
- 進程| 處理器時間百分比(總計或每個進程)–顯示整個計算機或特定進程的CPU使用率。可以說明很多問題。在掛起狀態的應用程序上,如果“處理器時間”已用完,則該過程將陷入無限循環之類的CPU約束操作中。如果處理器時間為0,則可能是死鎖或卡在I / O請求上。請注意,此數字最多可以達到100 * [邏輯CPU數]。因此,當您看到100%的值時,並不意味着CPU達到極限。
- 進程| 特權時間百分比–與”處理器時間百分比”類似,不同之處在於它僅包含處理器在內核模式下花費的時間。只有核心操作系統組件和某些驅動程序才能在內核模式下運行。在這種模式下,代碼可以執行任何操作並訪問任何內存地址。比如修改寄存器和啟用中斷。
- 進程| 用戶時間百分比–與“處理器時間百分比”類似,不同的是它僅包括處理器在用戶模式下花費的時間。也就是說,不是內核模式。
- 處理器| 處理器時間百分比–顯示每個線程而不是每個進程的處理器時間百分比。實例代表邏輯CPU內核。
內存的重要計數器
內存有3個主要類別:.NET CLR內存,用於托管內存,內存和進程。
- 專用字節–顯示已提交的進程內存(托管的和本機的)。這表示未與其他進程共享的內存。
- 虛擬字節–為進程分配的虛擬內存。這既是已用內存又是保留內存。它將始終等於或大於Private Bytes。它包括共享的DLL。
- 工作集–進程消耗的物理內存,包括其他進程也使用的共享DLL。
- #堆上的字節數–包括所有托管堆的總和– Gen 0 + Gen 1 + Gen 2 + LOH。這代表分配的托管內存大小。
監視內存泄漏的最佳計數器是專用字節。如果它繼續上升,那么程序可能出現內存泄漏。如果要區分是托管內存和還是本機內存的問題,請檢查#堆上字節數,以測量托管內存。如果它與“專用字節”一起增加,則是托管內存問題。如果在“專用字節”增加時它保持穩定,那么這就是本機內存問題。
- Gen X集合-回收器回收的次數。值得檢查性能問題。如果很高,則可能存在內存壓力(GC壓力)問題。特別是第二代收集應該是低的,因為那些收集非常慢。
ASP.NET重要計數器
僅當計算機上運行ASP.NET應用程序時,以下計數器才會激活。
- Web Service \ ISAPI擴展請求數/秒–在ASP.NET應用程序中每秒處理的請求數。
- 當前請求數–當前處理的請求數。正在排隊和正在執行。數字高可能表明存在問題。
- 應用程序重新啟動–應用程序重新啟動范圍很廣,可能會導致性能問題。重新啟動可能是由於Web.config,maching.config或global.asax的修改,bin目錄的修改或其他原因引起的。
有關ASP.NET計數器的非常有用且經過說明的列表,請參閱Microsoft文檔中的相關文章。
其他重要計數器
- 每秒拋出的異常數–每秒拋出大量異常會嚴重影響性能。這些通常是優先機會(已處理)異常。
- IO數據字節數/秒–進程發送和接收的字節數。
性能計數器代碼
.NET Framework中有一個非常簡單的API,可以使用System.Diagnostics.PerformanceCounter
類來自己監視性能。這是一個例子:
1 var currentProcess = Process.GetCurrentProcess().ProcessName; 2 PerformanceCounter privateBytes = 3 new PerformanceCounter(categoryName:"Process", counterName:"Private Bytes", instanceName:currentProcess); 4 PerformanceCounter gen2Collections = 5 new PerformanceCounter(categoryName:".NET CLR Memory", counterName:"# Gen 2 Collections", instanceName:currentProcess); 6 Debug.WriteLine("private bytes = " + privateBytes.NextValue()); 7 Debug.WriteLine("gen 2 collections = " + gen2Collections.NextValue()); 8
上面的代碼簡單地獲取2個計數器的當前值並打印日志。
創建自定義性能計數器也不太困難。我創建了一個示例,示范一個最沒用處的性能計數器。它報告當前的系統時間秒。這是代碼:
1 bool exists = PerformanceCounterCategory.Exists("MyTimeCategory"); 2 3 if (!exists) 4 5 { 6 7 PerformanceCounterCategory.Create("MyTimeCategory", "My category help", 8 9 PerformanceCounterCategoryType.SingleInstance, "Current Seconds", 10 11 "My counter help"); 12 13 } 14 15 PerformanceCounter pc = new PerformanceCounter("MyTimeCategory", "Current Seconds", false); 16 17 while (true) 18 19 { 20 21 Thread.Sleep(1000); 22 23 pc.RawValue = DateTime.Now.Second; 24 25 }
上面的代碼創建一個新的計數器(如果不存在)。在這種情況下,它是一個單實例計數器。每秒將計數器的值更新為系統時間秒。現在,我可以運行代碼,打開PerfMon並添加新的計數器。結果是這樣的:
總結
性能計數器是.NET調試和監測中非常有用的功能。盡管它們通常無法幫助您找到問題的根本原因,但性能計數器可以為我們指明正確的方向。例如,如果您遇到性能問題,則可以輕松查看它們是否與內存,CPU或異常太多等相關。
參考:michaelscodingspot