本文讨论咱们如何使用性能计数器从应用程序收集数据。咱们将先了解的基本知识,而后咱们将看到一个简单的示例,咱们将从中收集一些性能数据。less
介绍: - 个人应用程序的性能是最好的,像火箭
dom
让咱们这篇文章从一个客户和开发人员之间的简短交谈开始。函数
场景1性能
客户:- 大家的应用程序的性能怎么样?
主观的开发者:- Well,它真的很快,它是最好的... huuh aaa ooh,它就像火箭同样。测试
场景2网站
客户:- 大家的应用程序的性能怎么样?ui
量化的开发者:- 使用2 GB RAM,xyz处理器和20000客户记录的状况下,客户屏幕在20秒内加载完成。this
我确定比第一个开发的第二个开发者看起来更有前途的。在这篇文章中,咱们将探讨咱们如何使用性能计数器来测量应用程序的性能。让咱们开始计数1,2,3,4 ......es5
欢迎下载个人免费的500 Q&A电子书,内容涉及NET,ASP.NET,SQL Server,WCF,WPF,WWF@ http://www.questpond.com . (译者:做者在原文中作了一些广告,做为对他劳动成果的尊重,我将照原文翻译)
感谢Javier和Michael
我真的没有才智来写一些关于性能计数器的东西。但阅读下面的文章中,我能对付着写一些东西了。所以,首先请容许我感谢这些人,而后咱们再继续本文。
感谢Javier Canillas建立了performance counter helper,它确实简化了不少代码http://perfmoncounterhelper.codeplex.com/
感谢Michael Groeger精彩的文章,我从你的文章中摘取了计数器建立的代码http://www.codeproject.com/KB/dotnet/perfcounter.aspx
我也从如下文章中摘取了很多内容:
http://msdn.microsoft.com/en-us/library/system.diagnostics.performancecounter.aspx
归根结底,它们是:计数,计算(calculate)和显示
任何性能评估的工做无外乎计数,计算和显示。例如,若是你要计算在内存中每秒处理多少分页,咱们首先咱们须要对处理的页面的数量和其间流逝的时间(多少秒)进行计数。一旦咱们完成计数,咱们就须要进行计算,如用分页数除以秒数。最后,咱们须要显示咱们的性能数据。
如今,咱们知道这是一个3步骤的过程,即计数,计算和显示。计数的部分由应用程序来完成。所以,在计数阶段应用程序须要提供数据。请注意,数据不会被性能计数器自动检测到,而须要应用程序提供一些帮助。而计算和显示由性能计数器和监视器完成。
性能计数器不是魔术师
若是应用程序不提供计数器数据,性能计数器没法仅凭自身去衡量应用程序性能。性能计数器须要应用程序来提供性能数据用于衡量应用程序。换句话说,应用程序须要经过建立性能计数器对象来提供数据。
应用程序性能测量的类型
几乎全部的应用程序的性能测量属于如下六大类。
瞬时值:- 不少时候,咱们只是要测量当前值。例如,咱们但愿衡量有多少客户记录已被处理,有多少RAM内存已被使用等,这些指标被称为瞬时值或者绝对值。性能计数器经过瞬时计数器支持这些类型的测量。
平均值:- 有时瞬间/当前值并不展示真实的状况。例如,只是说应用程序消耗1GB的空间是不够的。可是,若是咱们可以获得某种内存消耗的平均数据,如1000个记录消耗的空间是10MB,也许你能够更深刻了解应用程序里面发生了什么。性能计数器经过使用像AverageBase,AverageTimer32,AverageCount64等类型支持这些种类型的测量。
速率值:- 有些状况下,当你想知道事件相对于时间的比率。例如,你想知道每秒有多少条记录被处理。速率计数器帮助咱们计算这些性能指标。
百分比值:- 不少时候,咱们想看到以百分比值来做比较。好比你要比较两台计算机之间的性能数据。比较直接的值将不会是一个公平的比较。所以,若是咱们能有两台计算机的%值,比较会更有意义。若是咱们要比较不一样性能计数器的值,百分比是更好的选择,而不是绝对值。
例如,若是你想把RAM使用状况和硬盘空间使用状况作比较。把50GB硬盘使用状况和1GB RAM的使用状况作比较,就如同比较苹果与橘子。若是你使用百分比来表达,这样的比较更公平和合理。百分比性能计数器能够帮助咱们以百分比来表达绝对值。
差别值:- 不少时候,咱们但愿获得差值的性能数据,好比从应用程序开始有多少时间流逝,从应用程序开始有多少硬盘消耗。为了收集这些类型的性能数据,咱们须要记录原始值和最新值。为了获得最终的性能数据,咱们须要从当前值减去原始值。性能计数器提供差值计数器计算这样的性能数据。
总之,有5种类型的性能计数器,可知足上述全部计数需求。正以下图所表现的:
将用于被性能计数器测试的示例程序
在整篇文章中,咱们将用接下来要说明的一个简单的程序做为计数器的例子。在这个例子中,咱们将有一个定时器,每隔100毫秒产生一个随机数。这些随机数将被检查看它是否小于2。若是是,那么函数‘MyFunction’将被调用。
下面的代码中,计时器将每100毫秒运行一次并产生随机数,若是随机数小于2则调用‘MyFunction’函数。
private void timer1_Tick(object sender, EventArgs e) { // Generate random number between 1 to 5. Random objRnd = new Random(); int y = objRnd.Next(1, 5); // If random number is less than 2 call my Function if (y > 2) { MyFunction(); } }
下面是'MyFunction'函数的代码,它是当随机数的值小于2时被调用的。该方法不会作任何事情。
private void MyFunction() { }
本文中咱们全部的性能计数器的例子,将使用上述定义的代码示例。
加入咱们的第一个瞬时性能计数器的4个步骤
在咱们深刻‘如何增长一个性能计数器’这个问题以前,让咱们先来了解一下性能计数器的结构。当咱们建立性能计数器,它须要被加入某些类别。所以,咱们须要建立一个类别,而且把全部性能计数器放在该类别下。
咱们来计数‘MyFunction’ 被调用了多少次。首先让咱们来建立一个名为“NumberOfTimeFunctionCalled”的即时计数器。在此以前,让咱们来看看有多少不一样类型的瞬时计数器被性能计数器所支持: -
一下定义摘自:http://msdn.microsoft.com/en-us/library/system.diagnostics.performancecountertype.aspx
NumberOfItems32:- 即时计数器,它显示最近观测到的值。
NumberOfItems64:- 即时计数器,它显示最近观测到的值。 例如,用于维护大量的项或操做的简单计数。 它与 NumberOfItems32 相同,但它使用更大的字段来容纳较大的值。
NumberOfItemsHEX32:- 即时计数器,它以十六进制形式显示最近观测到的值。 例如,用于维护项或操做的简单计数。
NumberOfItemsHEX64:- 即时计数器,它显示最近观测到的值。 例如,用于维护大量的项或操做的简单计数。 它与 NumberOfItemsHEX32相同,但它使用更大的字段来容纳较大的值。
第1步 建立计数器:- 对于咱们的当前的场景,‘NumberOfItems32’足够了。因此,咱们首先建立'NumberOfItems32‘即时计数器。有两种方式,一种是经过代码,另外一种是使用VS 2008的server explorer来建立计数器。代码的方法,咱们将在后面看到。如今咱们先使用server explorer来建立咱们的计数器。所以,打开您的Visual Studio,点击View,打开Server explorer,你会看到下面的图中所示的“Performance Counters”节点。右键单击“Performance Counters”节点,选择“create new category”。
当咱们建立了一个新的类别,您能够指定的类别名称,并在类别中添加计数器。对于当前的例子,咱们给定类别的名称为“MyApplication”,而且添加类型为'NumberOfItem32',名称为'NumberOfTimeFunctionCalled”的计数器。
第2步 在你的Visual Studio应用程序中添加计数器:- 一旦你已经把计数器添加到server explorer上,你能够把计数器控件拖放到ASPX页面上,以下图所示。
你须要把“只读”属性标记为false,这样你能够从代码中修改计数器的值。
第3步 添加为计数器计数的代码:- 最后,咱们须要递增计数器的值。窗体加载过程当中,咱们首先清除全部计数器的旧值。请注意,计数器的值是做为全局值保存的,因此他们不会本身重置,须要咱们显式地重置。所以,在窗体加载时把原始值设置为零。
private void Form1_Load(object sender, EventArgs e) { perfNumberOfTimeFunctionCalled.RawValue = 0; }
当函数被调用时,咱们经过使用‘Increment’方法来递增计数器的值。每次increment函数的调用,值增长1。
private void MyFunction() { perfNumberOfTimeFunctionCalled.Increment(); }
第4步 查看计数器数据:- 如今,咱们已经指定了计数器在每次‘MyFunction’函数被调用时,递增其值。如今咱们使用性能监视器(performance monitor)来显示性能计数器。打开‘Run’并输入‘perfmon’。你会看到有不少默认的性能计数器,清晰起见,咱们如今删除全部的计数器,加入咱们的性能计数器即‘NumberofTimeFunctionCalled‘。
如今,您能够看到以下图所示的图表。请确保您的应用程序正在运行,由于须要由应用程序发出数据,而后展示在performance monitor上。
上述视图是图表视图,要查看相同数据的文本格式,你可使用性能监视器提供的‘view report’选项卡。你能够看到该报告显示,从程序开始运行,‘MyFunction的’被调用了9696次。
建立更合理的计数器
在前面的章节中,咱们测量了‘MyFunction’被调用的次数。但这样的性能计数并无真正显示任何的测量价值。最好是,咱们也能看到计时器被调用次数,而后咱们就可以把计时器被调用的次数和‘MyFunction’被调用的次数作比较。
所以,咱们建立一个即时计数器,当定时器触发时递增该计数器。以下面的代码所示。
private void timer1_Tick(object sender, EventArgs e) { perfNumberOfTimeTimerCalled.Increment(); Random objRnd = new Random(); int y = objRnd.Next(1, 5); if (y > 2) { MyFunction(); } }
你能够在下面的图表中能够看到这两个计数器,蓝色的线表示‘MyFunction’被调用的次数,黑色的线表示timer被调用的次数。
若是咱们看一下‘report view’,咱们也能够看到timer被触发多少次,‘MyFunction’被调用多少次。
平均性能计数器
在前面的章节中,咱们用到了2个性能计数器,一个告诉咱们timer被触发了多少次,另外一个告诉咱们‘MyFunction’被调用了多少次。若是咱们能有某种平均数据,告诉咱们timer每调用一次‘MyFunctionCalled’计数多少次,它将更有意义。
为了获得这些类型的指标,须要用到平均性能计数器。所以,对于咱们的场景,咱们须要计数函数的调用次数和timer的触发次数。而后,咱们须要将他们相除,获得timer每触发一次函数调用多少次。
咱们须要添加两个计数器,一个做为分子另外一个做为分母。对于做为分子的计数器,咱们须要添加‘AverageCount64’类型的计数器,同时为分母,咱们须要添加‘AverageBase’类型的计数器。
在‘AverageCount64’类型计数器以后,你须要添加‘AverageBase‘计数器,不然,你会获得一个错误,以下图所示。
咱们对于每个timer触发,咱们都对用于记录timer调用的计数器进行递增。
private void timer1_Tick(object sender, EventArgs e) { perfAvgNumberofTimeTimerCalled.Increment(); Random objRnd = new Random(); int y = objRnd.Next(1, 5); if (y > 2) { MyFunction(); } }
为每一次函数调用咱们都对用于记录函数调用次数的计数器进行递增
private void MyFunction() { perfNumberOfTimeFunctionCalled.Increment(); }
若是你运行该程序,在view report模式下你应该会看到以下图所示。你能够看到平均‘MyFunction’被调用约0.5次(每timer触发一次)。
若是你本身作计算,你将获得和性能监视器相同的计算值。
速率性能计数器
在咱们的示例中,咱们如今想找出‘MyFunction’相对于时间的比率。咱们想知道每秒钟被调用了多少次。所以,浏览server explorer,并添加‘rateofCountsPerSecond32’计数器以下面的图所示。当‘MyFunction’每次被调用,递增此计数器。
若是您运行的应用程序,你将可以看到“RateofMyFunctionCalledPerSecond”的值。下面是一个简单的报告,该报告显示运行15秒后计数器的速率数据。在这15秒中总调用次数为72次。所以,平均每秒调用5次‘MyFunction’。
剩下的性能计数器
咱们还剩下百分比计数器和差别计数器,由于他们是很是简单和直接的,为了保持本文的焦点和特性,我在文中再也不介绍这两种计数器
经过C#代码添加计数器
到如今咱们已经经过server explorer来增长性能计数器。你还能够经过代码来添加计数器。第一件事就是,咱们须要导入System.Diagnostics命名空间。
而后,咱们须要建立‘CounterCreationDataCollection’ 对象。
CounterCreationDataCollection Mycounters = new CounterCreationDataCollection();
建立实际的计数器并指定计数器的类型。
CounterCreationData totalOps = new CounterCreationData(); totalOps.CounterName = "Numberofoperations"; totalOps.CounterHelp = "Total number of operations executed"; totalOps.CounterType = PerformanceCounterType.NumberOfItems32; Mycounters.Add(totalOps);
最后,在类别中建立计数器。下面的代码片段用于在‘MyCategory’类别中建立计数器。
PerformanceCounterCategory.Create("MyCategory","Sample category for Codeproject", Mycounters);
让咱们用Performance counter helper来缓解咱们的痛苦
写性能计数器建立代码是很痛苦的。使用performance counter helper能够帮助你缓解这种痛苦并使你的代码更小巧。你能够一下网站找到performance counter helper:http://perfmoncounterhelper.codeplex.com/
不要在产品中使用
是的,只在开发时使用性能计数器。若是您在产品中使用,确保有一个启用和禁用机制,不然会影响应用程序的性能。
使用性能计数器测量应用程序的数据。
性能计数器包含多种类型,如瞬时,平均,速率等。
性能计数器不该该在产品中用到。若是用到了,确保有一个禁用机制。
性能计数器自身并不能进行测量,它须要应用程序提供数据,这样性能监视器才能够计算并显示的数据。
源代码
从这里你能够找到并下载上述性能计数器讨论的示例源代码。
其余最佳实践
最佳实践第1部分,请单击此处
最佳实践第2部分,请单击此处
最佳实践第4部分,请单击此处
最佳实践第5部分,请单击此处
个人FAQ文章
(译者:广告时间)
我明白这不是谈论我FAQ文章正确的地方。只是想称赞一下本身花费一年时间来完成的FAQ系列。下面是所有的连接:
Silverlight FAQ :- http://www.codeproject.com/KB/WPF/WPFSilverLight.aspx
LINQ FAQ :- http://www.codeproject.com/KB/linq/LINQNewbie.aspx
WWF FAQ :- http://www.codeproject.com/KB/WF/WWF.aspx
WCF FAQ :- WCF.aspx
Sharepoint FAQ :- SharePoint.aspx
Ajax FAQ :- AjaxQuickFAQ.aspx
Architecture FAQ :- SoftArchInter1.aspx
Localization and globalization :- LocalizationGlobalizPart1.aspx
Project management FAQ :- ProjectManagementFAQ.aspx
关于做者
我是微软ASP / ASP.NET MVP,目前 |
本文由知平软件的刘斌华翻译,转载请注明出处。原文地址:http://www.codeproject.com/Articles/42001/NET-Best-Practice-No-3-Using-performance-counters
最佳实践1和2已经有其余网友翻译,一下给出连接:http://www.cnblogs.com/mickeychang/archive/2009/09/17/1568670.html
http://www.cnblogs.com/mickeychang/archive/2009/08/29/1556527.html
本人暂时没有翻译最佳实践4和5的计划。