使⽤dotTrace分析.NETCore代码问题
0.背景
在项⽬开发之中,前期可能主要以保证任务完成为主,对于性能优化主要在于开发完成之后再来进⾏。可能在测试的时候发现部分接⼝的代码执⾏时间过长,但是⼜毫⽆头绪,这个时候你就需要性能分析⼯具来协助你排查问题了。
常规性能分析借助于 Visual Studio 强⼤的性能测试⼯具就可以进⾏分析,但是这些功能只包含在企业版当中。这个时候我们就可以使⽤ JetBrains 的 .NET 分析全家桶来进⾏这个操作了,其包含内存分析(dotMemory)与性能分析(dotTrace),其实他的 dotCover(单元测试) 也是挺好⽤的。
1.安装与下载
1.1 下载
安装步骤较为简单,前往 Jetbrains 官⽹,到 dotTrace ,点击下载即可。
其地址为 ,选择⾃⼰需要的安装包形式,⼀般选择 WebInstaller 进⾏安装,当然这⾥推荐选择 Standalone (独⽴版),直接下载运⾏就 OK 。
1.2 安装
每个⽤户可以免费评估使⽤ 10 天,当然你要使⽤某些补丁或者激活⼯具也是可以的,这⾥不再详述过程,只是注意⼀下(WebInstaller)在安装的时候选择⾃⼰需要的安装就可以了,不需要的直接选为 Skip 跳过。
你也可以在安装的时候选择 "Visual Studio Integration",这样就会与 VS 集成,在分析代码的时候可以快速跳转到相应的代码⾏。
2.使⽤与分析
dotTrace 使⽤⽐较⽅便,本⾝⽀持 .NET Core 分析,分析时只是会有四种不同的分析模式,这⾥⼤概讲解⼀下各种分析模式的区别。
⼀般来说我们使⽤的是 Tracing  来进⾏代码的性能分析,因为⼀般都是需要查看每个⽅法具体的调⽤时间。下⾯我就将以⼀个接⼝的实例来作为⽰范,看如何来排查调⽤缓慢的问题。
2.1 获取快照信息
⾸先运⾏ dotTrace 之后,选择 .NET Core Application,之后右侧的 Profiler Options 则选择 Tracing。最后⼀步则是选择需要进⾏检测的 dll ⽂件,这⾥我选择的是⼀个基于Abp 框架开发的 ASP.NET Core 项⽬。Profiler Options
作⽤与描述Sampling 通过获取 CLR 内部⼀个⽅法开始执⾏和结束执⾏的时间差来计算的分析时间。
这是最快的⽅法,它⽤于精确测量程序运⾏时间,但可能会丢失⼀些数据。
使⽤此配置类型可使你快速获取应⽤程序的的总体性能。
Tracing 慢于 Sampling 的⽅法,但是可以准确地测量特定⽅法被调⽤的准确次数。
它是通过获取 CLR 内部⼀个⽅法开始执⾏和结束执⾏的时间差来计算的分
析时间。
Line-by-line 通过收集代码执⾏的每条语句的时间来进⾏⽐较,它计算出的时间更加精确。
该⽅法适⽤于你已经知道性能问题⼤概在哪⾥出现,并要到具体某⼀个出
现性能问题的时候。
Timeline
采取抽样的⽅式,每隔⼀段时间 (10 ms),会暂停所有线程,并抓取堆栈⾥的
信息,然后才计算出代码执⾏时间差。使⽤这个⽅式可能会导致⼀些执⾏时间
少于 10 ms 的⽅法⽆法被抓取到。
当然,你也可以勾选上 Advanced ,配置诸如启动参数之类的东西,之后点击 Run 则开始进⾏分析了。
这⾥右下⾓的 Get Snapshot and Wait 点击之后呢,就会获取到快照⽂件了,当然现在先不慌,我们先来测试⼀下我们要测试的接⼝。⽐如说我这⾥有⼀个 TestMethod ⽅法,其代码如下:
public class TestApplicationService : ApplicationService
{
private readonly IRepository<SysSystem> _tempRep;
public TestApplicationService(IRepository<SysSystem> tempRep)
{
_tempRep = tempRep;
}
public async Task<string> TestMethod()
{
var systems = _tempRep.GetAll().ToList();
foreach (var system in systems)
visual studio和vs code的区别{
system.Status = 10;
await _tempRep.UpdateAsync(system);
}
int i = 0;
for (int j = 0; j < 10000; j++)
{
i += j;
}
return systems[0].SystemCode;
}
}
现在我们通过 SwaggerUI 调⽤这个接⼝,看需要多长时间。
可以看到平均时常都需要 300ms ,现在我们点击 GetSnapshot and Wait 按钮,会弹出分析窗⼝,并且我们随时可以通过再次点击 Start 按钮,继续分析。
2.2 分析代码
2.2.1 概览信息
Tracing 分析的界⾯⽐较简单,⼀个 All Calls 页签与 Overview (概览) 的页签,⾸先我们⼤致看⼀下概览窗⼝。
可以看到他给我们标识了⽤户代码执⾏周期最长的⼀些地⽅,其次也⽤柱状图很直观地体现了耗时最长的代码分类。
右侧则提列了⼀些快照的信息与运⾏时的环境信息,以便⽤户作为参考。
2.2.2 Threads Tree (线程信息)
本窗⼝主要的作⽤是分析应⽤程序⾥⾯发⽣的所有的线程活动,主线程有⼀个  图标,⽽终结器线程则是拥有⼀个  图标,剩下的都是线程池内部的⼯作线程。
在这⾥我们以主线程为例,分析⼀下其具体内容所表达的意思。
Main:代表不带命名空间的⽅法简称。
99 . 99 %:代表该⽅法针对于整个线程运⾏时间所占的百分⽐,这⾥的意思就是 Main ⽅法占⽤了整个主线程运⾏时间的 99.99 %。
523,732 ms:代表该⽅法与⼦⽅法执⾏的总时间。
1 call:⽅法在堆栈上所被调⽤的次数。
XXX.Web.Host.Startup.Program.Main(string[] ):被调⽤⽅法的全称,
2.2.3 Call Tree (调⽤树)
⼀般我们使⽤本页⾯的时候会多⼀点,这个页⾯会显⽰在所有线程中的所有被调⽤的⽅法。其每⼀个根节点代表的是每⼀个线程所执⾏的⼀个根函数,⽽下⾯每⼀个节点则代表其根函数内部调⽤的⼦函数的相关性能分析信息。
那么我们如何快速定位我们刚才测试的接⼝呢?
按下 Ctrl+F ,会弹出搜索框,在⾥⾯输⼊我们所编写的接⼝⽅法名字,按下回车就会快速定位了。
之后我们会看到如下内容:

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