一:背景

1. 讲故事

在 dump 分析旅程中,经常会遇到很多朋友反馈一类问题,比如:

  • 方法平时都执行的特别快,但有时候会特别慢,怎么排查?
  • 我的方法第一次执行特别慢,能看到慢在哪里吗?

相信有朋友肯定说,加些日志不就好了,大方向肯定是没问题的,但加日志的颗粒度会比较粗而且侵入性也比较大,比如说这个方法不是你的,或者说这个方法是操作系统的,一般情况下对他们无法干涉,那如何洞察在你作用域之外的方法性能呢?作为 CLR团队首推的 PerfView 性能分析工具,必须要 KO 这些问题,接下来我们就简单聊一聊。

二:PerfView 洞察慢速方法

1. 测试代码

为了方便讲述,我们模拟这样的一种情况,一个方法第一次执行会特别慢(5s),后面执行都很快(3s),测试代码如下:


internal class Program
{
static void Main(string[] args)
{
mytest1(5000); for (int i = 0; i < int.MaxValue; i++) { }; mytest1(3000); Console.ReadLine();
} static void mytest1(int senconds)
{
Console.WriteLine("mytest1 start...");
Thread.Sleep(senconds);
Console.WriteLine("mytest1 end...");
}
}

那如何用 perfview 来洞察呢?玩过 perfview 的朋友都知道它是带时间轴的,我们可以对上面的慢速方法 mytest1 适当的放大,一直找到那一次的慢速调用,为了能够记录到 Thread 使用 CPU 的情况,需要开启 ThreadTime 选项,截图如下:

完整的 Command 命令如下:


PerfView.exe "/DataFile:PerfViewData.etl" /BufferSizeMB:256 /StackCompression /CircularMB:500 /KernelEvents:ThreadTime /ClrEvents:GC,Binder,Security,AppDomainResourceManagement,Contention,Exception,Threading,JITSymbols,Type,GCHeapSurvivalAndMovement,GCHeapAndTypeNames,Stack,ThreadTransfer,Codesymbols,Compilation /NoGui /NoNGenRundown /Merge:True /Zip:True collect

有了这些基础之后,先用 perfview 开启收集,然后执行应用程序,程序执行完成之后停止 perfview 收集,稍等片刻之后就有一个生成好的 zip 文件。

2. perfview 洞察

这里选择 Thread Time Stacks 视图,在弹框中选择我们的应用程序 ConsoleApp2,截图如下:

从卦象上看,当前的 ConsoleApp2 耗费了 3.2s 的CPU时间,总跟踪时间 17.19s

既然说了方法慢那必然是知道方法名的,只不过不知道慢在方法哪里,对应代码就是 mytest1() 方法,在 perfview 面板的 Find 输入框上搜索一下 mytest1 方法就可以找到,截图如下:

那这一行怎么解读呢? 我稍微说一下吧。

  • First:表示 mytest1 第一次被调用的时间戳
  • Last: 表示 myttest1 最后一次被释放的时间戳
  • when: 这里面是 32 个时间间隔的桶,每个桶的值是资源消化的比重。
  • TimeBucket: 一个桶的时间刻度,比如上图中的 633.8 ms

有了这些基础接下来就可以放大时间轴了,依次点击: First列 -> 右键菜单 -> Set Time Range ,放大后的截图如下:

When 列的 999999999999992________599999999 可以看到,当前这 11s 的挂钟时间内大概有两次 mytest1 调用,其实的 9 表示这个桶内消耗的单个资源的90%,我们要调查的就是其中 999999999999992 段,双击 When 列的 999999999999992 ,右键选择 Set Time Range 即可,截图如下:

放大到这里就差不多了,我们已经进入了第一次 mytest1 方法调用的作用域内,接下来依次点击 右键 -> Goto -> Goto Item in Callee 来观察下这个方法的下层到底都是写什么。

从卦中的 Inc 列来看,当前的 mytest1 方法耗费了 5.01s,其内部的 Thread.Sleep() 耗费了 5.005s ,这和测试代码中的 mytest1(5000); 不约而同。

哈哈,这不就找到了问题所在,在你的真实场景下,你可以继续观察底层的调用栈,找到问题所在。

三:总结

相信这篇能够给一些在慢速方法查找上有困惑的朋友找到一些灵感,还是那句话,CLR团队首推的 PerfView 在运行期监控方面是王者般的存在,与 WinDbg 优势互补。

PerfView专题 (第十五篇): 如何洞察 C# 中的慢速方法的更多相关文章

  1. PerfView专题 (第十二篇):对 C# 下的 SDK 类库进行监控(大结局)

    一:背景 本篇是我们系列文章的最后一篇,前面的文章中大多是在 CLR Runtime 以及 OS 层面进行监控来发现各种可疑的程序问题,除了这两个层面,其实我们还可以对 SDK 中一些类进行洞察,比如 ...

  2. 第二十五篇:在SOUI中做事件分发处理

    不同的SOUI控件可以产生不同的事件.SOUI系统中提供了两种事件处理方式:事件订阅 + 事件处理映射表(参见第八篇:SOUI中控件事件的响应) 事件订阅由于直接将事件及事件处理函数连接,不存在事件分 ...

  3. python学习之【第十五篇】:Python中的常用模块之time模块

    1.前言 在Python中,对时间的表示或操作通常要使用到time模块.本篇博文就来记录一下time模块中常用的几种时间表示转换方法. 2. 三种时间表示形式 2.1 时间戳 从1970年1月1日零点 ...

  4. 第十五篇:在SOUI中消息通讯

    SOUI是一套基于Win32 SDK的窗口开发的一套DirectUI框架.在SOUI中除了有真窗口使用窗口消息通讯机制外,还有SOUI控件之间的通讯,及控件的事件处理等. 1.真窗口消息通讯 因此可以 ...

  5. Python之路(第二十五篇) 面向对象初级:反射、内置方法

    [TOC] 一.反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它 ...

  6. 解剖SQLSERVER 第十五篇 SQLSERVER存储过程的源文本存放在哪里?(译)

    解剖SQLSERVER 第十五篇  SQLSERVER存储过程的源文本存放在哪里?(译) http://improve.dk/where-does-sql-server-store-the-sourc ...

  7. Python之路【第十五篇】:Web框架

    Python之路[第十五篇]:Web框架   Web框架本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. 1 2 3 4 5 6 ...

  8. 第十五篇 Integration Services:SSIS参数

    本篇文章是Integration Services系列的第十五篇,详细内容请参考原文. 简介在前一篇,我们使用SSDT-BI将第一个SSIS项目My_First_SSIS_Project升级/转换到S ...

  9. 【译】第十五篇 Integration Services:SSIS参数

    本篇文章是Integration Services系列的第十五篇,详细内容请参考原文. 简介在前一篇,我们使用SSDT-BI将第一个SSIS项目My_First_SSIS_Project升级/转换到S ...

  10. 跟我学SpringCloud | 第十五篇:微服务利剑之APM平台(一)Skywalking

    目录 SpringCloud系列教程 | 第十五篇:微服务利剑之APM平台(一)Skywalking 1. Skywalking概述 2. Skywalking主要功能 3. Skywalking主要 ...

随机推荐

  1. If选择语句的用法

    今天我们学习下If判断语句. 首先了解下它有几种用法: If单选择语句 If双选择语句 If多选择语句 我们一个一个用,每一个用法都给一个运用的过程演练一下. If单选择语句:我们很多需要判断一个东西 ...

  2. 线上诊断神器-arthas基本应用

    Arthas基本应用 一.Arthas作用 什么是Arthas呢? ​ Arthas 是一款阿里推出的线上监控诊断产品,通过全局视角实时查看应用 load.内存.gc.线程的状态信息,并能在不修改应用 ...

  3. 2021-12-22:回文子串。 给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。

    2021-12-22:回文子串. 给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目. 回文字符串 是正着读和倒过来读一样的字符串. 子字符串 是字符串中的由连续字符组成的一个序列. ...

  4. vue之关闭eslint及vue/require-v-for-key 、vue/no-unsed-vars报错解决方法

    报错:Page1组件已经注册但是没有被使用.  vue/no-unused-components 如果报错以下: 解决方法: 首先打开项目中的package,json 找到eslint-config ...

  5. 我写了本开源书:《3D编程模式》

    大家好,我写了本开源书,罗列了我从自己的实战项目中提炼出来的关于3D编程(主要包括"3D引擎/游戏引擎"."编辑器"开发)的各种编程模式 本书的在线阅读地址在这 ...

  6. 「GPT虚拟直播」实战篇|GPT接入虚拟人实现直播间弹幕回复

    摘要 ChatGPT和元宇宙都是当前数字化领域中非常热门的技术和应用.结合两者的优势和特点,可以探索出更多的应用场景和商业模式.例如,在元宇宙中使用ChatGPT进行自然语言交互,可以为用户提供更加智 ...

  7. 金三银四抢人季,HR 如何 3 招做到效率为王?

    春招伊始,面对队伍庞大的校招人群,蜂拥而入的简历,HR 如何才能快速搞定呢?Bug君总结了一下过往招聘季的一些比较流行的环节: 通过线上宣讲,节省出行成本.时间,老板更认可了 现在大多数企业都会在直播 ...

  8. Linux 中 3 个文件打包上传和下载相关命令详解

    tar 命令 通过 SSH 访问服务器,难免会要用到压缩,解压缩,打包,解包等,这时候tar 命令就是必不可少的一个功能强大的工具.Linux 中最流行的tar是麻雀虽小,五脏俱全,功能强大. 使用t ...

  9. Anaconda入门使用指南(二)

    Anaconda 安装完成,在 bin 子目录下( $PREFIX/bin )可以看到该发行版本预装好的 conda.python.pip.jupyter,以及一些常用的工具. Python环境管理 ...

  10. JeeCms低代码开发平台了解及认知以及遇到的问题

    1.jeecms低代码开发平台自带标签,使用的标签延续freemarker标签或基于freemarker标签自定的标签(类似自jsp自定义标签) (1)什么是freemarker标签: FreeMar ...