使⽤PerfView监测.NET程序性能(⼆):Perfview的使⽤
在中,我们了解了对Windows及应⽤程序进⾏性能分析的基础:Event Trace for Windows (ETW)。现在来看看基于ETW的性能分析⼯具——
Perfview简介
Perfview是⼀个开源的CPU和内存性能分析⼯具,也包括⼀些针对.NET的分析功能,例如GC分析,JIT分析,甚⾄ASP.NET中的请求统计等等。Perfview是⼀个Windows应⽤程序,但也能对在Linux系统上采集的数据进⾏分析()。Perfview免安装,⽽且只是⼀个14M的.exe⽂件,⾮常容易部署到需要进⾏性能分析的机器上,例如⽣产环境的服务器。⽽且在性能数据收集的过程中不需要重启应⽤程序或者服务器,⽽且收集的性能数据⽇志(.etl⽂件)可以被拷贝到其他Windows机器上,再进⾏分析⼯作,对业务的影响⾮常少。
Perfview已迁移到GitHub上,可以在上⾯下载,clone库或者查看相关资料。
Perfview GitHub:
Perfview视频教程:
Vance Morrison关于Perfview的博客:
Perfview使⽤
在简单介绍Perfview后,我们来使⽤Perfview进⾏⼀个⼩⼩的性能分析,来熟悉⼀下Perfivew的基本操作。
这个实验使⽤的代码,就是Vance Morrison在视频教程中⽤到的Console程序。代码可以在Perfivew⾃带的帮助⽂件中到。
using System;
// using System.Collections.Generic;
class Program
{
public static int aStatic = 0;
// Spin is a simple compute bound program that lasts for 5 seconds
// It is a useful test program for CPU profilers.
static int Main(string[] args)
{
int numSec = 5;
if (args.Length == 1)
numSec = int.Parse(args[0]);
Console.WriteLine("Spinning for {0} seconds", numSec);
RecSpin(numSec);
return0;
}
// Spin for 'timeSec' seconds.  We do only 1 second in this
// method, doing the rest in the helper.
static void RecSpin(int timeSec)
{
if (timeSec <= 0)
return;
--timeSec;
SpinForASecond();
RecSpinHelper(timeSec);
}
// RecSpinHelper is a clone of RecSpin.  It is repeated
// to simulate mutual recursion (more interesting example)
static void RecSpinHelper(int timeSec)
{
if (timeSec <= 0)
return;
--timeSec;
SpinForASecond();
RecSpin(timeSec);
}
// SpingForASecond repeatedly calls DateTime.Now until for
// 1 second.  It also does some work of its own in this
// methods so we get some exclusive time to look at.
static void SpinForASecond()
{
DateTime start = DateTime.Now;
for (; ; )
{
if ((DateTime.Now - start).TotalSeconds > 1)
break;
// Do some work in this routine as well.
for (int i = 0; i < 10; i++)
aStatic += i;
}
}
}
以上代码很简单,SpinForASecond()在⼀秒内不断调⽤DateTIme.Now,⽽RecSpin()和RecSpinHelper()则不断地相互调⽤对⽅。这⾥使⽤循环的⽬的是,循环执⾏是⼀种典型的CPU密集型操作,⽽RecSpin()和RecSpinHelper()则是为了丰富程序的函数调⽤栈。
步骤⼀:收集程序运⾏数据,⽣成由ETW数据组成的.etl⽂件。
Perfview提供两种收集数据的⽅式,Run和Collect。“Run”是直接指定需要启动的应⽤程序的名称,以便启动该程序。“Collect”则是直接启动Perfview并开始收集。但不要以为"Run"⽅式只收集指定程序的数据。事实上⽆论哪种⽅式,Perfview都会收集系统范围内全部数据,并且收集完成后,需要选择某⼀个进程以进⾏分析。
在弹出的对话框中,填⼊需要启动的全⽂件名,以及填⼊⽣成etl⽂件的⽂件名(这⾥是l),并点击“Run Command”:
writeline方法的作用Perfview收集和处理数据的时间⽐较长。在处理过程中,Perfview的右下⾓会闪动,并且可以查看运⾏⽇志,了解到当前Perfview在执⾏什么⼯作。
步骤⼆:选择需要分析的进程
在收集完毕后,在左边选择“l.zip”,并在展开的选择项中双击选择“CPU Stacks”,此时,会弹出进程选择对话框,选择需要进⾏CPU分析的进程。这⾥选择我们
运⾏的进程。
在双击选择了“”的进程后,进⼊到程序详细的执⾏栈的视图中。这⾥记录着的函数调⽤树,以及函数的执⾏时间。
在该视图中,你可以看到的函数调⽤情况,包括函数调⽤树(Call-Tree),某个函数的调⽤者(Calls)和被该函数调⽤的函数(Callees),另外,在视图右侧,是函数的执⾏时间,其中,“Exc”是指 Exclusive,是指函数⾃⼰(不包含该函数⾥执⾏的⼦函数)的执⾏时间,⽽“Inc”是指Inclusive,指该函数及该函数中执⾏的⼦函数的总的执⾏时间。
另外,这个执⾏时间是怎么认定的呢?答案是CPU采样。Perfview对CPU进⾏采样,默认每个CPU采样是1毫秒(在Prefview的⾼级设置中可以设置到0.125毫秒~1毫秒),每次采样中可以得到当前CPU正则执⾏什么代码。例如DateTime_getNow()有3250采样,则可以说明在整个程序运⾏中,DateTime_getNow()占⽤了3250毫秒的CPU时间,占整个运⾏时间的66.2%。通过⽐较各个函数的执⾏时间,我们就可以知道程序中哪个函数占⽤⽐较多的CPU时间。
以上便是Prefview的基本的使⽤步骤。Prefview提供了⾮常多并强⼤的功能,例如分组(Grouping),折叠(Folding),时间范围选择,这些在后续教程⾥再聊。⽽更强⼤的是,F1帮助⼿册⾥,有着⾮常详细的使⽤说明和术语解析,⽽且界⾯上⼏乎每个功能都有说明的ToolTip和说明的超链接如果对某个功能⽤法不是很清楚,可以⽅便地到说明,真是业界良⼼。
参考资料
系列⽬录

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。