概述
JetBrains dotTrace(2020.01)
Tracing模式:耗时方法分析
Line-By-Line模式:耗时代码行分析
JetBrains dotMemory(2020.01)
稀疏数组
析构队列
1,JetBrains dotTrace性能诊断
JetBrains dotTrace是JetBrains家族的产品成员;它可以安装集成再Visula studio中,也可以独立使用;主要用于.NET平台下的性能分析;
该工具相对于Visula studio的诊断工具和windows性能监视器相比,对于定位性能的问题更加详细;
截至2020年9月;JetBrains dotTrace最新版本是2020.2;JetBrains dotTrace是收费的;我没有找到2020.2的破解版;使用的是2020.1的破解版的
下面来介绍一下JetBrains dotTrace2020.1在Visula studio2019环境下的使用(JetBrains dotTrace2020.1是要自己下载安装的)
打开Visula studio2019的菜单上的"扩展";选择"ReSharper">"Profile">"Run Startup Configuration Performance Profiling";如下图
打开之后,你将会看到一个关于跟踪模式的选项问话;一共有四种模式;如下说明
Simpling:获取CLR内部的方法的开始时间,结束时间差,用于获取程序的运行时间,分析速度快
Tracing:比Simpling慢,用于测量特定的方法被调用的次数,以及程序的时间差
Line-By-Line:收集每条代码的运行时间来比较,计算出更加精确的运行时间;用于定位具体的性能语句时
TimeLine:类似于vs分析工具的性能抽样的方式,可能会导致一些执行时间特别短的方法抓取不到
Tracing模式:方法调用时间分析Tracing模式
下面我们使用Tracing模式来进行测试,并查看每个方法的运行时间,调用次数等信息;如下运行测试后自动生成的报告
All Calls:以调用线程列表展现所有线程耗时;包含了查看自身调用时间,总调用时间
展开Main Thread主线程;点击展开;你可以查看每一个线程上的各个方法的耗时情况,每个方法的开销占比
点击方法,还可以看到对应源码
调用链视图;与线程视图不同;调用链视图是以方法的维度查看方法的性能状况;还可以展开方法的内部调用;
选择某个方法;右键查看方法统计状况属性;可以看到更简洁的性能统计视图:总消耗时间,自消耗时间,平均消耗时间,调用次数等
如果你发现某些方法的自身调用时间占比比较低,那么说明真正调用时间较长的还在子方法调用,你可以选择该方法,右键属性查看所有方法;
查看指定方法的所有子方法
普通列表视图;
视图平铺的方式展示所有被调用的方法,展示每个方法的平均调用,总调用时间,自身调用时间
热点调用视图;将性能监视最重要的,最消耗性能的相关调用在这进行展示
总览视图:以图表方式展现概况
Line-By-Line模式:分析定位最耗时的代码行
Tracing模式只能看到每一个方法,线程相关的调用时间;但是你无法定位到是那一段代码,那一句代码最耗时;
使用Line-By-Line模式可以分析定位最耗时的代码行;如下Line-By-Line耗时统计结果,你可以看到每行调用次数
在"调用次数数值"旁边有蓝色横条柱;用来标识每行代码占用开销的比例
数字是调用次数;蓝色横条是开销占比
1,JetBrains dotMemory内存诊断
JetBrains dotMemory是JetBrains家族的产品成员;它可以安装集成再Visula studio中,也可以独立使用;主要用于.NET平台下的内存开销的分析;
该工具相对于Visula studio的诊断工具,更加强大;
截至2020年9月;JetBrains dotMemory最新版本是2020.2;JetBrains dotTrace是收费的;我没有找到2020.2的破解版;使用的是2020.1的破解版的;
一般情况下,在你安装JetBrains dotTrace时,你也可以选择安装JetBrains dotMemory
下面来介绍一下JetBrains dotMemory2020.1在Visula studio2019环境下的使用(JetBrains dotMemory2020.1是要自己下载安装的)
打开Visula studio2019的菜单上的"扩展";选择"ReSharper">"Profile">"Run Startup Project Memory Profiling";在弹出的对话框中选择Run(选择默认值)
内存跟踪界面
你可以看到当前的
总内存开销;
非托管内存
GC的0-2代内存堆,大对象堆
移动到曲线图上,你还可以每一个时间点上的内存状况;如下图
查看GC内存回收时的内存,持续时间内内存状况;抓取内存快照
如托管堆的内存,总内存等
按上图,点击打开内存快照链接;查看内存快照更加详细的视图
你可以看到快照时间上,各个对象的内存分配状况,最大可存活对象;以及常见的内存回收存在问题的诊断;如
Sparse Arrays(稀疏数组)
Finalizable Objects(析构队列)
String duplicates(字符串重复)
如上图,分析内存问题
存在大量Byte西数数组,就是数组中有很多都是默认值0;点击查看占用内存开销43.36MB的Byte[]对象;你会发现里面都是被0填充的
析构队列:
回收对象时会调用对象的析构函数,垃圾回收时执行这些析构函数,那么使得垃圾回收的时间无法预料;
为了解决这个问题,.NET定义了析构线程和析构队列;如果对象不再存活,而且你又定义了析构函数;那么对象将会被添加到析构队列,并且标记它为存活;在本轮GC中将不会回收这些对象
GC结束后,析构线程会去取出析构队列中的对象来执行析构函数,析构函数执行完毕的对象会在下一轮GC中回收
析构队列存在大量Employee对象;是因为Employee重写了析构函数;在析构函数中做了业务逻辑
导致Employee的回收速度比Employee的内存分配速度慢(一个在new,一个在释放,释放的速度比new的慢,这将会导致内存溢出)
如下析构函数