.NET 性能测试工具 -- 事件跟踪器(ETW)

本文介绍了Windows系统中用于性能分析的内置工具和第三方工具,包括EventTracing for Windows (ETW)、Windows Performance Toolkit (WPT)、WindowsPerformanceRecorder (wpr.exe) 和WindowsPerformanceAnalyzer (wpa.exe),以及如何使用这些工具进行内存、CPU、硬盘I/O等关键资源的分析。文章还涉及了自定义ETW Providers和基于ETW的性能数据统计工具的开发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内容预告:

  • Windows内置工具(性能计数器)
  • 事件跟踪器(WPT,PerfMoniter,PerfView,自定义ETW)
  • 时间分析
  • 内存分配分析
  • 内存使用量分析
  • 其他分析

Event Tracing for Windows(ETW)可以查看很多内核和CLR的性能数据,如下表所示,有几个工具都是基于ETW开发的,后面会详细介绍:

KernelPROC_THREADCreation and destruction of processes and threads 
KernelLOADERLoad and unload of images (DLLs, drivers, EXEs) 
KernelSYSCALLSystem calls 
KernelDISK_IODisk I/O reads and writes (including head location) 
KernelHARD_FAULTSPage faults that resulted in disk I/O (not satisfied from memory) 
KernelPROFILESampling event—a stack trace of all processors collected every 1ms 
CLRGCKeywordGarbage collection statistics and informationCollection started, collection ended, finalizers run, ~100KB of memory have been allocated
CLRContentionKeywordThreads contend for a managed lockContention starts (a thread begins waiting), contention ends
CLRJITTracingKeywordJust in time compiler (JIT) informationMethod inlining succeeded, method inlining failed
CLRExceptionKeywordExceptions that are thrown 

 

 

 

 

 

 

 

Windows Performance Toolkit (WPT)是ETW的工具集,捕获ETW事件到日志文件。可以在http://msdn.microsoft.com/en-us/performance/cc752957.aspx 下载。

使用步骤如下:

  1. 在环境变量里将_NT_SYMBOL_PATH的值设置到微软的公开符号服务器和本地符号缓存,如C:\Temp\Symbols*http://msdl.microsoft.com/download/symbols
  2. 在环境变量里_NT_SYMCACHE_PATH的值设置到一个自定义目录。
  3. 打开管理员权限的cmd窗口定位到安装文件夹(如C:\Program Files\Windows Kits\8.0\Windows Performance Toolkit)。
  4. 运行xperf -on Base开始跟踪内核数据
  5. 随便运行一些程序
  6. 停止跟踪,输出日志。xperf -d KernelTrace.etl
  7. 打开图形分析器 xperfview KernelTrace.etl

WPT的运用场景是:

  • 捕获硬盘IO操作

  • 提供所有CPU的活动

  • 显示IO,内存,CPU等的叠加图

  • 显示调用栈

最新的Windows SDK8.0包含一些新工具,叫做Windows Performance Recorder (wpr.exe) 和Windows Performance Analyzer (wpa.exe), 是为了替代XPerf 和XPerfView的。wpr -start和xperf -on相同,wpr -stop和xperf -d 一样。WPA分析UI和XPerfView的功能一样,更多信息可以参考 http://msdn.microsoft.com/en-us/library/hh162962.aspx.

 XPerfView可以看GC事件的数据:

 


PerfMonitor是一个开源的控制台工具 http://bcl.codeplex.com/releases/view/49601.

PerfMonitor的优点是可以更细节地分析CLR和JIT。

使用方法如下:

C:\PerfMonitor > perfmonitor runAnalyze JackCompiler.exe
Starting kernel tracing. Output file: PerfMonitorOutput.kernel.etl
Starting user model tracing. Output file: PerfMonitorOutput.etl
Starting at 4/7/2012 12:33:40 PM
Current Directory C:\PerfMonitor
Executing: JackCompiler.exe {
} Stopping at 4/7/2012 12:33:42 PM = 1.724 sec
Stopping tracing for sessions 'NT Kernel Logger' and 'PerfMonitorSession'.
Analyzing data in C:\PerfMonitor\PerfMonitorOutput.etlx
GC Time HTML Report in C:\PerfMonitor\PerfMonitorOutput.GCTime.html
JIT Time HTML Report in C:\PerfMonitor\PerfMonitorOutput.jitTime.html
Filtering to process JackCompiler (1372). Started at 1372.000 msec.
Filtering to Time region [0.000, 1391.346] msec
CPU Time HTML report in C:\PerfMonitor\PerfMonitorOutput.cpuTime.html
Filtering to process JackCompiler (1372). Started at 1372.000 msec.
Perf Analysis HTML report in C:\PerfMonitor\PerfMonitorOutput.analyze.html
PerfMonitor processing time: 7.172 secs.

上面的统计结果包括:

  • CPU统计,CPU利用率。
  • GC统计,GC时间,最大GC堆是4.5MB,内存分配速率最高是1496.1MB/秒,平均GC暂停时间是0.1MS。
  • JIT编译统计,159个函数在运行时被JIT编译,共30493个机器字节。

下图表明CPU做的最多的工作是这3个函数:System.String.Concat, JackCompiler.Tokenizer.Advance, 和System.Linq.Enumerable.Contains

 84.2%的CPU时间花在了:JackCompiler.Parser.Parse, 调用了ParseClass, ParseSubDecls, ParseSubDecl, ParseSubBody

 

 下图是一些GC事件的细节统计:

 


PerfView:一个免费工具,可以分析堆的使用。在http://www.microsoft.com/download/en/details.aspx?id=28567 下载。

 上面的报告包括了:

  • 原始的ETW事件列表。
  • CPU在栈上使用时间的分组。
  • 镜象加载,硬盘IO,GC使用栈的情况。
  • GC统计。

PerfView还可以生成堆的快照。

 


自定义 ETW Providers:也可以自己开发基于ETW的性能数据统计工具。.NET4.5之前输出ETW数据相当困难,.NET4.5要容易很多了,继承System.Diagnostics.Tracing.EventSource类然后调用 WriteEvent函数就可以输出了。

public class CustomEventSource : EventSource {
public class Keywords {
public const EventKeywords Loop = (EventKeywords)1;
public const EventKeywords Method = (EventKeywords)2;
}
[Event(1, Level = EventLevel.Verbose, Keywords = Keywords.Loop,
Message = "Loop {0} iteration {1}")]
public void LoopIteration(string loopTitle, int iteration) {
WriteEvent(1, loopTitle, iteration);
}
[Event(2, Level = EventLevel.Informational, Keywords = Keywords.Loop,
Message = "Loop {0} done")]
public void LoopDone(string loopTitle) {
WriteEvent(2, loopTitle);
}
[Event(3, Level = EventLevel.Informational, Keywords = Keywords.Method,
Message = "Method {0} done")]
public void MethodDone([CallerMemberName] string methodName = null) {
WriteEvent(3, methodName);
}
}
class Program {
static void Main(string[] args) {
CustomEventSource log = new CustomEventSource();
for (int i = 0; i < 10; ++i) {
Thread.Sleep(50);
log.LoopIteration("MainLoop", i);
}
log.LoopDone("MainLoop");
Thread.Sleep(100);
log.MethodDone();
}
}

PerfMonitor工具可以自动从程序获得ETW的事件数据:

C:\PerfMonitor > perfmonitor monitorDump Ch02.exe
Starting kernel tracing. Output file: PerfMonitorOutput.kernel.etl
Starting user model tracing. Output file: PerfMonitorOutput.etl
Found Provider CustomEventSource Guid ff6a40d2-5116-5555-675b-4468e821162e
Enabling provider ff6a40d2-5116-5555-675b-4468e821162e level: Verbose keywords:
0xffffffffffffffff
Starting at 4/7/2012 1:44:00 PM
Current Directory C:\PerfMonitor
Executing: Ch02.exe {
} Stopping at 4/7/2012 1:44:01 PM = 0.693 sec
Stopping tracing for sessions 'NT Kernel Logger' and 'PerfMonitorSession'.
Converting C:\PerfMonitor\PerfMonitorOutput.etlx to an XML file.
Output in C:\PerfMonitor\PerfMonitorOutput.dump.xml
PerfMonitor processing time: 1.886 secs.

 

其实还有一个东西叫做Windows Management Instrumentation (WMI).这里没有提到,它可以获取到系统状态,BIOS固件,等数据。文档见http://msdn.microsoft.com/en-us/library/windows/desktop/aa394582.aspx

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<think>好的,用户现在问的是有什么工具可以自动分析代码性能和bug的。我需要先回顾之前的对话,看看用户之前的问题是什么。之前用户提到他们用WinForms+DevExpress+C#开发的HIS应用程序出现了偶发的卡顿或卡死,但业务代码量大,问题难以复现,所以需要分析日志和代码来找原因。现在用户可能是在进一步寻求工具来辅助他们自动分析代码,而不是完全手动检查。 首先,用户的需求可能分为两部分:性能分析和bug检测。他们可能希望找到一些自动化工具,能够集成到开发流程中,帮助他们快速定位问题,尤其是偶发性的问题。考虑到他们使用的是C#和WinForms,可能需要推荐针对.NET生态系统的工具。 接下来,我需要回忆常见的C#代码分析工具。比如,Visual Studio自带的性能分析器和诊断工具,JetBrains的dotTrace和dotMemory,还有像ReSharper这样的代码质量工具。另外,对于内存泄漏,用户可能需要内存分析工具,比如ANTS Memory Profiler或者.NET Memory Profiler。 关于静态代码分析,SonarQube是一个很好的选择,可以集成到CI/CD中,检查代码质量和潜在漏洞。对于数据库性能,可能需要推荐SQL Server Profiler或EF Core的相关工具,比如EF Core的日志记录或LINQPad来优化查询。 另外,用户之前提到了DevExpress控件,可能控件本身的使用问题也会导致性能问题,所以需要推荐检查控件使用情况的工具或者方法,比如DevExpress官方提供的性能指南或诊断工具。 还要考虑用户提到的偶发问题,可能需要一些监控工具,比如Application Insights,用于实时监控应用程序性能,捕获异常和跟踪请求。此外,像Glimpse这样的工具也可以帮助在开发阶段实时诊断ASP.NET应用,不过用户是WinForms,可能需要其他工具。 对于多线程和死锁问题,可能需要推荐Concurrency Visualizer或者使用WinDbg来分析转储文件。还有像PostSharp这样的AOP框架,可以帮助在代码中自动插入性能追踪的代码。 用户可能还需要开源工具,比如Benchmark.NET用于性能测试,或者NUnit、xUnit的测试框架结合Coverlet来检测代码覆盖率,确保测试覆盖到潜在的问题区域。 最后,需要总结这些工具,并给出一个分层的建议,比如开发阶段、测试阶段、生产环境分别使用哪些工具,或者按问题类型(性能、内存、死锁、代码质量)分类推荐,帮助用户根据具体情况选择合适的工具。</think>以下是针对代码性能与缺陷自动分析的实用工具分类指南,结合不同开发阶段和问题类型提供解决方案: --- ### **一、代码质量与安全扫描** #### 1. **静态代码分析** | 工具名称 | 适用场景 | 技术亮点 | |----------------|-----------------------------|----------------------------| | **SonarQube** | 多语言代码质量门禁 | 自定义规则集+技术债可视化 | | **ReSharper** | C#实时代码检查 | 智能重构建议+代码异味检测 | | **Roslyn分析器**| .NET编译时检查 | 深度集成VS+自定义诊断规则 | ```csharp // 示例:通过Roslyn检测async void问题 [DiagnosticAnalyzer(LanguageNames.CSharp)] public class AsyncVoidAnalyzer : DiagnosticAnalyzer { public override void Analyze(SyntaxNodeAnalysisContext context) { // 检查方法签名中的async void } } ``` #### 2. **架构合规检查** - **NDepend**: 生成代码依赖矩阵,检测循环引用、方法圈复杂度超标等问题 ```plaintext // 查询高复杂度方法 FROM METHODS WHERE CyclomaticComplexity > 15 ``` --- ### **二、运行时性能诊断** #### 1. **性能剖析工具** | 工具名称 | 数据采集方式 | 典型用途 | |------------------|--------------------------|--------------------------| | **dotTrace** | 采样/跟踪/逐行 | 函数耗时分布分析 | | **PerfView** | ETW事件收集 | GC压力/线程竞争诊断 | | **JetBrains Profiler** | 内存/CPU/线程三合一 | 界面交互性能优化 | ```plaintext # 使用PerfView捕获高GC压力 1. 启动Collect -> Run命令 2. 筛选 ".NET GC Heap Alloc Ignore Free(μs)" ``` #### 2. **内存泄漏检测** - **dotMemory**: 对比内存快照,识别未释放对象引用链 ```csharp // 示例泄漏代码 public static List<Patient> _cache = new List<Patient>(); // 静态集合未清理 ``` - **Visual Studio内存诊断**: 内置堆分析功能,快速定位托管堆异常 --- ### **三、并发与死锁检测** #### 1. **多线程调试工具** | 工具名称 | 核心能力 | 使用场景 | |-------------------|-------------------------|------------------------| | **Concurrency Visualizer** | 线程活动可视化 | 分析UI线程阻塞 | | **OzCode Parallel Watch** | 实时查看并行变量状态 | 调试TPL数据流问题 | #### 2. **死锁自动检测** - **Thread Debugger** (VS扩展): 自动识别锁顺序反转问题 ```csharp // 风险代码模式 lock (objA) { lock (objB) { ... } // 另一线程可能以相反顺序锁定 } ``` --- ### **四、数据库性能分析** #### 1. **SQL监控工具** | 工具名称 | 数据库类型 | 关键功能 | |--------------------|----------------|-----------------------| | **SQL Profiler** | SQL Server | 实时跟踪查询执行计划 | | **EF Core日志** | Entity Framework | LINQ转SQL效率分析 | | **pgBadger** | PostgreSQL | 慢查询日志可视化 | ```csharp // 启用EF Core详细日志 optionsBuilder.UseSqlServer(connStr) .EnableSensitiveDataLogging() .LogTo(Console.WriteLine, LogLevel.Information); ``` #### 2. **ORM优化工具** - **LINQPad**: 快速测试LINQ语句执行效率,对比不同写法性能差异 - **Dapper**: 对高负载模块进行SQL直写优化 --- ### **五、自动化测试与监控** #### 1. **性能基准测试** - **BenchmarkDotNet**: 精确测量代码段执行时间 ```csharp [SimpleJob(RuntimeMoniker.Net60)] public class EncryptionBenchmarks { [Benchmark] public void AES_Encrypt() { /* 测试代码 */ } } ``` #### 2. **生产环境监控** | 工具名称 | 数据维度 | 集成方案 | |----------------------|---------------|---------------------| | **Application Insights** | 端到端追踪 | Azure生态无缝对接 | | **Prometheus+Grafana** | 自定义指标 | 容器化环境首选 | | **New Relic** | 全栈性能监控 | SaaS快速接入 | --- ### **六、专项问题检测工具** #### 1. **WinForms特有工具 - **Windows Performance Analyzer**: 分析UI线程消息处理延迟 ```plaintext 关键事件序列: Win32Proc -> User Input -> .NET事件处理 -> 控件渲染 ``` #### 2. **DevExpress专项检测 - **DXperience诊断中心**: 内置控件性能分析模块 ```csharp // 检查GridControl渲染瓶颈 gridView.OptionsView.EnableAppearanceEvenRow = false; gridView.OptionsView.ShowGroupPanel = false; ``` --- ### **实施建议:** 1. **开发阶段**:SonarQube+ReSharper+单元测试覆盖率(Coverlet) 2. **测试阶段**:dotTrace+dotMemory+LoadRunner压力测试 3. **生产环境**:Application Insights+自定义健康检查API 4. **紧急排查**:Procdump+WinDbg内存转储分析 通过工具链的层级化部署,可覆盖从代码编写到线上运维的全生命周期质量保障。建议优先建立静态代码分析流水线,再结合动态分析工具定位运行时问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值