前言
由于系统越来越大,流程及业余已经趋于稳定,所以当前优化的任务提上了日程,所以当前的主要的关注点由功能的开发转向了业务流程的梳理及性能的优化,本文主要介绍使用vs的自带的性能探查器来定位接口中内存及CPU使用率较高的地方,以达到提高接口的吞吐量和减少内存溢出风险的目的
1.分析CPU使用情况
1.1准备工作
1.IDE:VS2019
2.官方cpu耗时代码一份
using System;
using System.Threading;
public class ServerClass
{
const int MIN_ITERATIONS = int.MaxValue / 1000;
const int MAX_ITERATIONS = MIN_ITERATIONS + 10000;
long m_totalIterations = 0;
readonly object m_totalItersLock = new object();
// The method that will be called when the thread is started.
public void DoWork()
{
Console.WriteLine(
"ServerClass.InstanceMethod is running on another thread.");
var x = GetNumber();
}
private int GetNumber()
{
var rand = new Random();
var iters = rand.Next(MIN_ITERATIONS, MAX_ITERATIONS);
var result = 0;
lock (m_totalItersLock)
{
m_totalIterations += iters;
}
// we're just spinning here
// and using Random to frustrate compiler optimizations
for (var i = 0; i < iters; i++)
{
result = rand.Next();
}
return result;
}
}
public class Simple
{
public static void Main()
{
for (int i = 0; i < 200; i++)
{
CreateThreads();
}
}
public static void CreateThreads()
{
ServerClass serverObject = new ServerClass();
Thread InstanceCaller = new Thread(new ThreadStart(serverObject.DoWork));
// Start the thread.
InstanceCaller.Start();
Console.WriteLine("The Main() thread calls this after "
+ "starting the new InstanceCaller thread.");
}
}
1.2.收集分析数据
1.设置两个断点
通过两个断点可以将数据收集限定在指定的想要分析的代码的部分
2.启动项目
启动项目如下图
分析CUP主要观察右侧CPU使用率(记得把记录CPU配置文件点亮) 如果未出现右方的诊断工具则可以通过调试-->窗口-->显示诊断工具来显示,或者ctrl+alt+F2来显示
3.运行到下一个断点的地方
会出现下图场景
到此收集完毕
1.3.分析收集到的CPU使用率的数据
1.3.1.分析cpu使用率的数据首先应该聚焦到右下方列表中
其中:
1.上部分列表排行是以耗费CPU较高的的函数降序排列的
2.函数名中出现外部调用、外部代码、本机等字样
a.外部调用为调用本方法
b.外部代码:官方解释为: 由代码执行的系统和框架函数称为“外部代码”。 外部代码函数启动和停止应用、绘 制 UI、控制线程以及向应用提供其他低级别服务 ,此部分不需要去关注
c.本机
d.只需关注没有标识的代码调用
3.CPU总计表示调用函数所使用的毫秒数和CPU百分比,
4.自CPU时间范围内调用函数所使用的的毫秒数和CPU占比,不包含调用其他函数耗费
1.3.2. 在函数列表中,单击 ServerClass.GetNumber
函数。
如下图
右击框选的图标选择【加载模块符号】/【加载所有符号】可以显示下方的具体代码信息
上面CPU总计为2296(94.44%) 自CPU为1(0.04%)
下方两个1(0.04%) 、 2295(94.44%)
对应上耗时的地方可以看出1毫秒的为自CPU的部分2295毫秒为调用其他方法的地方,2295毫秒的为调用其他方法的耗时,总耗时为2296毫秒
接下来看一下GetNumber()
左侧可以看出比较耗时的地方由此可以分析出rand.Next()是最为耗时的地方
1.3.3.也可以通过切换当前视图来用其他方式查看
如上图切换为调用方\被调用方的视图
其中
1.左侧为调用当前函数的函数
2.中间为当前函数
3右侧为当前函数调用的函数--》其中排行第一的为最耗时的函数,可以点击进入下一个调用视图
1.3.4 如果想要查看外部代码可以通过如下方式查看
点击筛选器-->勾选选择外部代码-->应用
1.4.也可以通过性能探查器来查看当前接口的CPU使用率
调试-->性能探查器
勾选上CPU使用率的选项、选择更改目标,然后开始,分析方式也和以上相同
2.分析内存使用情况
2.1准备工作
来上才艺
准备了一个内存泄漏的代码
using System;
using System.Collections.Generic;
class Program
{
private static Processor p = new Processor();
static void Main()
{
int it = (20000 * 100);
for (int i = 0; i < it; i++)
{
p.ProcessTransaction(new Customer(Guid.NewGuid().ToString()));
}
}
}
class Customer
{
private string id;
public Customer(string id)
{
this.id = id;
}
}
class CustomerCache
{
private List<Customer> cache = new List<Customer>();
public void AddCustomer(Customer c)
{
cache.Add(c);
}
}
class Processor
{
private CustomerCache cache = new CustomerCache();
public void ProcessTransaction(Customer customer)
{
cache.AddCustomer(customer);
}
}
2.2 收集内存分析数据
如上图打上断点
初始状态下点击截取快照
运行到下一步-->点击截取快照
会出现两个快照
说明:对象差异列展示相比于上个快照对象的变化 为增加对象 绿色箭头为减少对象
堆大小差异列展示相比上个快照内存的变化同上红色箭头为增加绿色箭头为减少
2.3分析快照
点击单个快照如下图
说明:
1.可以与其他的快照对比查看增加或减少了那些对象和大小
2.下部分的“根的路径”树显示引用上部分选中的对象,只有当引用某个对象的最后一个类型已经释放时,垃圾回收器才会清理该对象的内存
3.“引用的类型” 树显示持有上部分选中对象的引用
4.如果想看选中类型的实例则可以点击下图的图标
如下图
鼠标悬浮在对应的实例上可以查看对应实例的值
参考文章:https://docs.microsoft.com/zh-cn/visualstudio/profiling/?view=vs-2019
性能优化 tony