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