性能監視器是一個 Microsoft 管理控制台 (MMC) 管理單元,提供用於分析系統性能的工具。僅從一個單獨的控制台,即可實時監視應用程序和硬件性能,自定義要在日志中收集的數據,定義警報和自動操作的閾值,生成報告以及以各種方式查看過去的性能數據。
啟動 Windows 性能監視器:搜索欄輸入 perfmon --> 回車。
一、常用計數器
運行截圖:
常用的監視計數器:
對象 |
計數器 |
說明 |
.NET CLR Exceptions | # of Exceps Thrown / sec | 顯示每秒鍾拋出的異常數。這包括 .NET 異常和轉換為 .NET 異常的未受管異常。性能隨此數目的增大而下降。 |
.NET CLR Memory | # Bytes in all Heaps | 顯示其他四個計數器的總和:Gen 0 堆大小、Gen 1 堆大小、Gen 2 堆大小以及大對象堆大小。此計數器表示 GC 堆上當前分配的內存(以字節為單位)。此計數器的值總是比 Process\Private Bytes 的值小,Process\Private Bytes 對進程的 MEM_COMMIT 區域進行計數。Private Bytes minus # Bytes in all Heaps 就是由未受管對象提交的字節數。 用於監視可能的內存泄漏,或者監視受管或未受管對象的內存使用率是否過大。 |
.NET CLR Remoting | Remote Calls/sec | 顯示每秒調用的遠程過程調用的數目。遠程過程調用是對調用方所在應用程序域之外的任何對象的調用。此計數器不是一段時間內的平均值;它顯示最近兩個樣本觀測值的差除以取樣間隔所得的結果。 |
.NET Data Provider for Oracle | NumberOfFreeConnections | 連接池中可用連接的數量。 |
.NET Data Provider for SqlServer | NumberOfFreeConnections | 連接池中可用連接的數量。 |
Process | % Processor Time | 顯示所有進程線程用於執行指令的已用處理器時間的百分比。指令是計算機中的基本執行單位;線程是執行指令的對象;進程是運行程序時創建的對象。此計數中包含了處理某些硬件中斷和陷阱條件時執行的代碼。如果總的處理器時間較長,請使用此計數器確定導致 CPU 利用率很高的進程。 |
Process | Handle Count | 顯示此進程當前打開的句柄的總數。此數字是此進程中的每個線程當前打開的句柄總數。特定進程中句柄計數的增加可能是發生句柄泄漏的錯誤進程的症狀,這將導致服務器上發生性能問題。此問題並不一定會出現,但是在一段時間內對其進行監視以確定是否發生句柄泄漏十分重要。 |
Process | Thread Count | 這個進程中正在活動的線程數目。指令是在處理器中基本的執行單位,線程是指執行指令的對象。每個運行的進程至少有一個線程。 |
SQLServer:General Statistics | User Connections | 顯示sqlserver目前連接的數量,而不是用戶數。如果該計數器超過255,那么你需要將sqlserver的"Maximum Worker Threads" 的配置值設置得比缺省值255高。如果連接的數量超過可用的線程數,那么sqlserver將共享線程,這樣會影響性能。"Maximum Worker Threads"需要設置得比你服務器曾經達到的最大連接數更高。 |
SQLServer:Locks | Number of Deadlocks/sec | 死鎖的數量/秒,死鎖對應用程序的可伸縮性非常有害,並且會導致惡劣的用戶體驗。該計數器的值必須為0。 |
LogicalDisk | % Free Space | % Free Space 是所選邏輯磁盤驅動器上總計可用空間所占的百分比。 |
PhysicalDisk | Disk Read Bytes/sec | 指在讀取操作時從磁盤上傳送字節的速率。 |
PhysicalDisk | Disk Write Bytes/sec | 指在寫入操作時傳送到磁盤上的字節速度。 |
默認狀況下,以下兩個計數器的開關是關着的,需要配置下 %WINDIR%\microsoft.net\Framework64\v4.0.30319\Config\machine.config 如下開關的(32和64位操作系統的路徑不同),否則數據采集不到。
.NET Data Provider for Oracle | NumberOfFreeConnections |
.NET Data Provider for SqlServer | NumberOfFreeConnections |
增加配置,並重啟相應的進程(重啟服務 或 重啟IIS等)。
<system.diagnostics> <switches> <add name="ConnectionPoolPerformanceCounterDetail" value="4"/> </switches> </system.diagnostics>
二、用C#采集計數器的數據
雖然Windows自帶了perfmon工具,並可以生成報告以及以各種方式查看過去的性能數據,但是有時候我們還是定義自己的一些曲線或者報表,那么就需要將性能監視器的數據收集起來,C#提供了PerformanceCounterCategory(性能對象),PerformanceCounter(性能計數器組件)兩個類,提供了操作性能監視器的一些方法,這樣我們就能把數據讀取出來保存到數據庫中或者文件中,可用來隨意產生一些曲線或報表,或者報警Mail等。
using System; using System.Diagnostics; using System.Threading; namespace TestApplication { public class Program { static void Main(string[] args) { Console.WriteLine(GetPerfCount("Process", "% Processor Time", "_Total")); Console.WriteLine(GetPerfCount(".NET CLR Memory", "# Bytes in all Heaps", "_Global_")); Console.WriteLine(GetPerfCount("SQLServer:General Statistics", "User Connections")); Console.Read(); } /// <summary> /// 獲取計數器樣本並為其返回計算所得值--有實例的計數器(對於大多數的計數器) /// </summary> /// <param name="categoryName"></param> /// <param name="counterName"></param> /// <param name="instance"></param> /// <returns></returns> public static float GetPerfCount(string categoryName, string counterName, string instance) { PerformanceCounter counter = new PerformanceCounter { CategoryName = categoryName, CounterName = counterName, InstanceName = instance, MachineName = ".", ReadOnly = true }; counter.NextValue(); Thread.Sleep(200); try { if (counter != null) { return counter.NextValue(); } } catch (Exception) { return -2f; } return -1f; } /// <summary> /// 獲取計數器樣本並為其返回計算所得值--無實例的計數器 /// 比如categoryName=SQLServer:General Statistics,counterName=User Connections /// </summary> /// <param name="categoryName"></param> /// <param name="counterName"></param> /// <returns></returns> public static float GetPerfCount(string categoryName, string counterName) { PerformanceCounter counter = new PerformanceCounter { CategoryName = categoryName, CounterName = counterName }; counter.NextValue(); Thread.Sleep(200); try { if (counter != null) { return counter.NextValue(); } } catch (Exception) { return -2f; } return -1f; } } }