首页 > 系统相关 >用 perfcollect 洞察 Linux 上.NET程序 CPU爆高

用 perfcollect 洞察 Linux 上.NET程序 CPU爆高

时间:2023-07-18 09:57:16浏览次数:41  
标签:00 perf 爆高 ConsoleApp1 perfcollect -- Linux root localhost

一:背景

1. 讲故事

如果要分析 Linux上的 .NET程序 CPU 爆高,按以往的个性我肯定是抓个 dump 下来做事后分析,这种分析模式虽然不重但也不轻,还需要一定的底层知识,那有没有傻瓜式的 CPU 爆高分析方式呢?

相信有很多朋友知道 B站713事件,最终就是用 perf 找到了那个让 cpu 100% 的 lua 函数,截图如下:

这里我们也借助 perf 这款工具实现 .NET程序的 cpu 爆高洞察, perf 就不过多介绍了,它是Linux系统中提供的一款性能分析工具,类似 Windows 的 ETW 跟踪,所以对他的了解是非常重要的。

这里要注意的是我们并不直接使用,而是用微软提供的基于 perf 的高层封装工具 perfCollect,它不仅能收集 perf 能收集的事件,还能收集 .NET 中的 EventSource 事件,简直是福音哈。

PerfCollect 跟踪

1. 测试代码

为了能够让 CPU 爆高,我们故意让其中一个方法死循环,一个方法运行一段时间正常结束,参考代码如下:


namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Task.Run(() =>
            {
                Test1();
            });

            Task.Run(() =>
            {
                Test2();
            });

            Console.ReadLine();
        }

        static void Test1()
        {
            int i = 1;
            bool b = false;

            while (i > 0)
            {
                b = !b;
            }
        }

        static void Test2()
        {
            for (int i = 0; i < short.MaxValue; i++)
            {

            }
        }
    }
}

代码有了就可以 publish 到 centos 上,接下来在 /etc/profile 中增加一个环境变量 export COMPlus_PerfMapEnabled=1 ,目的是让 RIP 能够成功解析到 C# 的方法名,截图如下:

有了这些前置基础,接下来就是把程序跑起来,用 htop 观察下 CPU 的利用率。


[root@localhost data2]# vim /etc/profile
[root@localhost data2]# source /etc/profile
[root@localhost data2]# ls
ConsoleApp1  ConsoleApp1.deps.json  ConsoleApp1.dll  ConsoleApp1.pdb  ConsoleApp1.runtimeconfig.json
[root@localhost data2]# dotnet ConsoleApp1.dll

2. 安装 PerfCollect

刚才也说了 PerfCollect 是微软提供的一款工具,集成了 perf + LTTng 两块,前者用于捕获Linux系统级事件,后者用于捕获 CoreCLR 以及 EventSource 事件,接下来就是下载,赋权限,安装。


[root@localhost data3]# curl -OL https://aka.ms/perfcollect
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:02 --:--:--     0
100 68590  100 68590    0     0  17540      0  0:00:03  0:00:03 --:--:-- 72658
[root@localhost data3]# chmod +x perfcollect
[root@localhost data3]# sudo ./perfcollect install
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
epel/x86_64/metalink                                                              |  28 kB  00:00:00     
 * base: ftp.sjtu.edu.cn
 * epel: d2lzkl7pfhq30w.cloudfront.net
 * extras: mirror.lzu.edu.cn
 * updates: mirror.lzu.edu.cn
base                                                                              | 3.6 kB  00:00:00     
docker-ce-stable                                                                  | 3.5 kB  00:00:00     
extras                                                                            | 2.9 kB  00:00:00     
packages-microsoft-com-prod                                                       | 1.5 kB  00:00:00     
updates                                                                           | 2.9 kB  00:00:00     
Package perf-3.10.0-1160.92.1.el7.x86_64 already installed and latest version
Package zip-3.0-11.el7.x86_64 already installed and latest version
Package unzip-6.0-24.el7_9.x86_64 already installed and latest version
Nothing to do
LTTng already installed.

安装好之后进行 10s 采集,采集完之后就会生成一个 ConsoleApp.trace.zip 文件,输出如下:


[root@localhost data3]# ./perfcollect collect ConsoleApp -collectsec 10
Collection started. Collection will automatically stop in 10 second(s). Press CTRL+C to stop early.

...STOPPED.

Starting post-processing. This may take some time.

Generating native image symbol files
...FINISHED
Saving native symbols
...FINISHED
Resolving JIT and R2R symbols
...FINISHED
Exporting perf.data file
...FINISHED
Compressing trace files
...FINISHED
Cleaning up artifacts
...FINISHED

Trace saved to ConsoleApp.trace.zip

最后把 ConsoleApp.trace.zip 复制到 Windows 平台上用 PerfView 分析。

3. Perfview 分析

说句良心话,Perfview 真的是太强大了,什么文件都能从中提取有用信息,比如 .dmp,.nettrace 还有这里的 .zip ,用 Perfview 打开 zip 之后,双击 CPU Stacks 选项,找到我们的 PID 进程即(.NET ThreadPool),截图如下:


[root@localhost data3]# ps -ef | grep dotnet
root       6027   3171 99 23:33 pts/1    00:02:01 dotnet ConsoleApp1.dll
root       6529   5240  0 23:35 pts/2    00:00:00 grep --color=auto dotnet

双击打开之后,去掉 GroupPats 信息,可以看到占比最高的是 Program::Test1() 方法。

有朋友可能要问这个信息怎么解读呢?其实非常简单,perf 也是按照 1ms 采样一次的方式,所以 10s 的样本数: 1w =10 * 1000

从上图中可以看到,总的采样到了 9999 个样本,其中 Program::Test1() 占据了 9993,占比高达 99.9%,到这里我们就定位出了原来这个函数就是 hot 函数。

三:总结

不知道大家发现没有,在 Windows 上很容易监控的东西,在 Linux 上就要麻烦的多,其实很容易理解,Windows 是微软的, .NET 也是微软的,自然是一等公民的存在。

图片名称

标签:00,perf,爆高,ConsoleApp1,perfcollect,--,Linux,root,localhost
From: https://www.cnblogs.com/huangxincheng/p/17561965.html

相关文章

  • Linux常用命令
    文件和目录操作ls/pwd/cd/touch/mkdir/cp/mv/rm/cat/less/grep/head/tail/查找文件 find通常用来在特定目录下搜索符合条件的文件查找指定路径下扩展名是.py的文件,包括子目录find[路径]-name"*.py"如果省略路径,表示在当前文件夹下查找在使用find命令时也可以用通配......
  • Linux内存管理 - 大页 (三)
    静态大页可以通过两种方法来设置1.检查/proc/meminfo,确认系统支持HugePageHugePages_Total:系统中配置的大页数HugePages_Free:没有访问过的大页数HugePage_Rsvd: 已经分配但是还未使用的页面数2. 配置静态大页通过在bootargs传参在系统启动过程......
  • Django+DRF+Vue 网页开发环境安装(windows/Linux)
    博客地址:https://www.cnblogs.com/zylyehuo/总览一、安装Djangopipinstalldjango==3.2二、安装MySQL驱动程序pipinstallpymysql三、安装DRFpipinstalldjangorestframework-ihttps://pypi.douban.com/simple四、安装Vue(一)脚本化引入<scriptsrc=......
  • linux Mysql 备份与还原
    数据库是企业中非常重要的部分,数据是企业的根本,不可丢失的,需要备份和还原。目录一、数据备份的重要性二、数据库备份类型三、常见的备份方法四、MySQL完全备份五、数据库完全备份分类六、实战案列七、总结   一、数据备份的重要性1.数据备份的重要......
  • linux进程
    程序运行在操作系统中,被操作系统所管理,每一个程序在运行时都会被操作系统注册为系统中的一个进程,并为每一个进程分配一个独有的进程ID(进程号PID)1.linux查看进程ps[-e-f]选项-e,显示全部进程选项-f,以完全格式化的形式展示信息UID:进程所属用户PID:进程的进程号PPID:进程的父ID(启......
  • linux 中查看glibc版本
     001、查看软链接[root@PC1software]#ls-l/lib64/libc.so.6lrwxrwxrwx.1rootroot12Jul1717:22/lib64/libc.so.6->libc-2.17.so 002、执行   /lib64/libc.so.6[root@PC1software]#/lib64/libc.so.6GNUCLibrary(GNUlibc)stablereleaseversio......
  • 正点原子第五十八章 Linux input子系统实验 文档之外(没提到的部分)
    使用input子系统,不需要分配设备号、注册设备、创建类等等工作。也就是不需要以下的代码。//1.由系统分配设备号if(Key_Struct.major!=0){Key_Struct.devid=MKDEV(Key_Struct.major,0);register_chrdev_region(Key_Struct.devid,DEV_C......
  • Linux内存管理 - 大页 (二)
    为了解决页表项过多的问题,Linux提供了两种机制,就是多级页表和大页。 一.在阐述大页的优点之前,先来看一下内存映射的页表结构。 PGD: PageGlobalDirectoryPUD:Page UpperDirectoryPMD:PageMiddleDirectoryPTE: PageTableEntry二.TLB......
  • Linux网络编程(socket的udp通信)
    UDP是无连接的,即发送数据之前不需要建立连接,它尽最大努力交付,即不保证可靠交付,在一些要求实时性的通信中多有用到如游戏,视频等,UDP是面向报文的,有别于tcp的一对一通信,udp支持一对一、一对多、多对一和多对多的交互通信等。 一、udp通信用到的相关函数解析intsocket(intdoma......
  • Linux磁盘专题
    物理磁盘名次和其作用盘片:disk盘片上下都有磁头。磁盘面:盘片有上下两面,每一面叫磁盘面磁头:heads每个磁头负责一个磁盘面,负责读取数据、将数据写入磁道。磁头都是固定在机械臂上(机械臂就是磁头臂组支架)磁道:track每个磁盘面上围绕圆心划分出多个同心圆环,每个圆圈叫做磁......