商城首页欢迎来到中国正版软件门户

您的位置:首页 >C# PerfView使用教程:性能分析全攻略

C# PerfView使用教程:性能分析全攻略

  发布于2026-03-14 阅读(0)

扫一扫,手机访问

PerfView 是基于 ETW 的高性能事件采集分析器,专治 GC 频繁、JIT 开销大、线程阻塞、异步堆积、内存泄漏、ThreadPool 饱和等 .NET 难定位性能问题;它无插桩、低开销、可捕获 CLR 内部事件。

C# PerfView使用入门方法 C#如何使用PerfView进行深度性能分析

PerfView 是什么,它能帮你解决哪类 C# 性能问题

PerfView 不是传统意义上的“ profiler UI 工具”,而是一个基于 ETW(Event Tracing for Windows)的高性能事件采集与分析器。它特别适合诊断 .NET 应用中那些“跑得慢但看不出卡在哪”的问题:比如 GC 频繁、JIT 编译开销大、线程阻塞、异步等待堆积、内存泄漏嫌疑、甚至 ThreadPool 饱和导致的吞吐下降。

它不依赖代码插桩,对运行时影响极小(尤其在采样模式下),且能捕获 CLR 内部事件(如 GCStartJitJittedMethodILToNativeMapThreadPoolWorkerThreadStart),这是很多第三方工具做不到的。

如何启动一次最小可行的 PerfView 录制(.NET 6+ / .NET Core 场景)

  • 确保目标进程是 .NET 6 或更高版本(旧版需额外配置 DOTNET_STARTUP_HOOKS 或启用 LegacyETW)
  • 下载最新 PerfView.exe(无需安装,单文件),以管理员权限运行(部分事件需要)
  • 使用命令行启动录制,避免 GUI 操作引入干扰:
    PerfView.exe collect -CollectMultiple -NoGui -CircularMB:512 -Merge:true -Zip:true MyApp.exe
  • 其中关键参数:
    • -CollectMultiple:同时采集多个进程(含子进程),适合 ASP.NET Core 自托管或带子进程的场景
    • -CircularMB:512:环形缓冲区大小,防止磁盘爆满;实际分析时再加 -LogFile:xxx.etl.zip 指定输出
    • -Merge:true:自动合并多进程事件,避免手动关联
  • 不要勾选 “Include Input Events” 或 “Heap Dump”,除非你明确需要 UI 输入延迟或对象快照——它们显著增加开销和体积

打开 etl.zip 后,该看哪几个视图定位 C# 瓶颈

PerfView 默认打开的是“Events”视图,但真正高效分析要切到这几个标签页:

  • GC Heap Alloc View:直接显示每个方法分配了多少字节,按 Alloc MB 排序,一眼揪出高频临时对象创建点(比如 string.ConcatEnumerable.ToList、JSON 序列化中的中间字符串)
  • Call Tree(by Weight):右键选择 “Group Pats → By Module → By Method”,展开后重点关注:
    • 耗时占比高的 clr!JIT_* 调用 → JIT 编译热点(可能因泛型爆炸或动态代码)
    • 大量 coreclr!SVR::gc_heap::allocate_more_space → GC 压力大,配合 GC Heap Alloc 看谁在猛分配
    • 线程长时间停在 ntdll!NtWaitForSingleObject → 查看其调用栈上层是否为 Task.WaitGetAwaiter().GetResult() 或锁竞争
  • Processes → [YourApp] → Threads:观察线程状态分布,若大量线程处于 “Blocked” 或 “Sleeping” 且堆栈指向 Monitor.EnterConcurrentQueue.Enqueue,说明同步瓶颈明显

常见误操作和容易被忽略的细节

  • 直接双击 .exe 启动 PerfView GUI 再点 “Collect” → 很可能漏掉进程启动初期的关键事件(如 JIT、AssemblyLoad)。必须用命令行 + collect 参数启动目标进程
  • 在 .NET 5+ 中未设置环境变量就尝试抓取 GC 详细事件 → 需提前运行:
    set COMPLUS_GCStress=0 & set DOTNET_gcServer=1
    (后者确保服务端 GC 开启,否则 GCHeapStats 事件不全)
  • PerfView.exe 放在中文路径下运行 → 某些版本会因路径编码失败静默退出,一律用英文路径
  • 分析 ASP.NET Core 应用时没启用 Microsoft-AspNetCore-Server-IISMicrosoft-Extensions-Logging provider → 导致无法关联请求生命周期,应在录制命令中加:
    -Providers:Microsoft-AspNetCore-Server-Kestrel;Microsoft-Extensions-Logging

PerfView 的深度不在界面有多炫,而在你能看到 CLR 运行时“没说出口”的话。真正难的不是采集,而是读懂那些看似杂乱的事件链——比如一个 ThreadPoolWorkerThreadStart 后紧跟着三次 ThreadPoolWorkerThreadStop,往往意味着线程被频繁销毁重建,背后可能是 Task.Run 被滥用或 async void 导致异常逃逸。

本文转载于:互联网 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注