前言
由於系統越來越大,流程及業余已經趨於穩定,所以當前優化的任務提上了日程,所以當前的主要的關注點由功能的開發轉向了業務流程的梳理及性能的優化,本文主要介紹使用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