PerfView专题 (第十二篇):对 C# 下的 SDK 类库进行监控(大结局)
一:背景
本篇是我们系列文章的最后一篇,前面的文章中大多是在 CLR Runtime 以及 OS 层面进行监控来发现各种可疑的程序问题,除了这两个层面,其实我们还可以对 SDK 中一些类进行洞察,比如说:
ArrayPool
Http
Socket
Task
更多资料可以看下:https://docs.microsoft.com/en-us/dotnet/core/diagnostics/well-known-event-providers
接下来就来个简单的抛砖引玉
二:如何洞察
1. ArrayPool 监控
之所以对 ArrayPool 感兴趣,主要还是因为在分析 Dump 的过程中,遇到过几起 LOH 碎片化问题,比如使用第三方模板生成引擎生成 Html 导致大量临时性 char[], byte[],终导致 LOH 破败不堪,所以最后给出的建议是使用这种池化的 ArrayPool,如果可以监控池的租借情况,那是不是挺好的? 哈哈,还真有这样的 ETW,截图如下:

为了方便讲解,先上一段简单的测试代码:
internal class Program
{
static void Main(string[] args)
{
var shared = ArrayPool<int>.Shared;
var rentedArray = shared.Rent(10);
for (int i = 0; i < 10; i++)
{
rentedArray[i] = i + 1;
}
for (int j = 0; j < 10; j++)
{
Console.WriteLine(rentedArray[j]);
}
shared.Return(rentedArray);
Console.ReadKey();
}
}
接下来启动 Perfview,在 Additional Providers 上输入:
*System.Buffers.ArrayPoolEventSource:::@StacksEnabled=true
然后开启 Start Collection 观察 Array 的租借情况,稍等片刻后,在 Event 中搜索 ArrayPool 可以看到相关的 ETW 事件,截图如下:

在 Rent 列的 bufferSize="16" 中可知,当前租借了一个 size=16 的数组。
HasStack="True" ThreadID="15,060" ProcessorNumber="10" bufferId="32,854,180" bufferSize="16" poolId="27,252,167" bucketId="-1"
因为开启了 Stack 功能,可以在 Time MSec 列上右键选择 Open Any Stacks,在弹窗中可以轻松找到这个 rent 所在的代码,截图如下:

2. Http 监控
对 Http 的监控也是由于最近遇到了一个比较头疼的 dump 有感而发的,一个朋友的 dump 出现了 cpu 100% 的情况,我分析下来发现是程序在短时间内出现了大量的 Http Exception,进一步排查怀疑是 sdk 里面的异常,由于被吞了所以上层获取不到,也就找不到是第三方 sdk 哪里的代码块出的问题。
这里的找不到或者很难找到是在 WinDBG 场景下,其实借助 PerfView 还是比较好发现的,途径就是开启 System.Net.Http ETW 事件,它内置了 14 个,太强大了,截图如下:

为了方便讲述,先上一段测试代码。
internal class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 5; i++)
{
GetString();
}
Console.ReadLine();
}
static async void GetString()
{
try
{
HttpClient client = new HttpClient();
var html = await client.GetStringAsync("https://cnblogs1.com");
Console.WriteLine(html);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}

这段代码会抛出异常,然后在 catch 中给吞掉了,因为抛了异常,就可以观察它的 RequestFailed 事件,然后找到对应的 RequestStart 事件,再观察它的调用栈即可。
接下来在 PerfView 中设置 *System.Net.Http:::@StacksEnabled=true,再开启收集按钮,稍等片刻点击 Event 面板,搜集 Http 事件,截图如下:

从面板中可以清晰的观察到当前有 5 个请求失败,并且还带了关联的 ActivityID, 接下来可以找 ActivityID=/#18920/1/29/ 对应的 Request/Start 事件。

然后在 Time MSec 列上右键点击 Open Any Stacks 按钮,可以轻松的看到,那个 Request/Start 事件是 GetString() 方法触发的,截图如下:

3. 总结
总的来说,在 .NET 调试领域,让 PerfView 适当的配合 WinDbg,真的可以 如虎添翼 ,好了,本系列就先写到这里,感谢朋友们对本系列的持续关注。
PerfView专题 (第十二篇):对 C# 下的 SDK 类库进行监控(大结局)的更多相关文章
- 解剖SQLSERVER 第十二篇 OrcaMDF 行压缩支持(译)
解剖SQLSERVER 第十二篇 OrcaMDF 行压缩支持(译) http://improve.dk/orcamdf-row-compression-support/ 在这两个月的断断续续的开发 ...
- 第十二篇 SQL Server代理多服务器管理
本篇文章是SQL Server代理系列的第十二篇,详细内容请参考原文 在这一系列的上一篇,我们查看了维护计划,一个维护计划可能会创建多个作业,多个计划.你还简单地看了SSIS子系统,并查看了维护计划作 ...
- 第十二篇 Integration Services:高级日志记录
本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...
- Python之路【第十二篇】:JavaScrpt -暂无内容-待更新
Python之路[第十二篇]:JavaScrpt -暂无内容-待更新
- Python开发【第二十二篇】:Web框架之Django【进阶】
Python开发[第二十二篇]:Web框架之Django[进阶] 猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 ...
- 【译】第十二篇 Integration Services:高级日志记录
本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...
- 【译】第十二篇 SQL Server代理多服务器管理
本篇文章是SQL Server代理系列的第十二篇,详细内容请参考原文 在这一系列的上一篇,我们查看了维护计划,一个维护计划可能会创建多个作业,多个计划.你还简单地看了SSIS子系统,并查看了维护计划作 ...
- 专题开发十二:JEECG微云高速开发平台-基础用户权限
专题开发十二:JEECG微云高速开发平台-基础用户权限 11.3.4自己定义button权限 Jeecg中.眼下button权限设置,是通过对平台自己封装的button标签(<t:dgFun ...
- 跟我学SpringCloud | 第十二篇:Spring Cloud Gateway初探
SpringCloud系列教程 | 第十二篇:Spring Cloud Gateway初探 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如 ...
随机推荐
- ShardingSphere-proxy-5.0.0部署之分表实现(一)
一.说明 环境准备:JDK8+ mysql 5.x 官网:https://shardingsphere.apache.org/ 下载地址:https://archive.apache.org/ ...
- LVGL库入门教程03-布局方式
LVGL布局方式 LVGL的布局 上一节介绍了如何在 LVGL 中创建控件.如果在创建控件时不给控件安排布局,那么控件默认会被放在父容器的左上角. 可以使用 lv_obj_set_pos(obj, x ...
- VMware Workstation 虚拟机安装教程
一.介绍篇 VMware Workstation 16 Pro是VMware(威睿公司)于2021年最新发布的一代虚拟机软件,软件的中文名是"VMware 工作站 16 专业版". ...
- RPA 抖音机器人汇总
一.RPA 抖音小店催好评机器人 RPA机器人详情: 1.配置好抖音小店订单号与催好评话术 2.启动抖音小店催好评机器人 3.机器人打开飞鸽客服软件 4.自动搜索订单号,自动发送催好评内容 5.机器人 ...
- 搭建zabbix及报错处理
搭建ZABBIX服务器准备工作 1.需要服务器是LAMP 或 LNMP 环境 2.主机名和IP要写在HOST文件里 3.iptables 和 selinux 必须关闭 一.先用最简单的方式搭建lamp ...
- linux目录结构及定时任务
1. Linux的根目录(最顶层的目录) windows系统有根目录:c盘的根目录就是c:\ d盘的根目录就是d:\ 每个盘(分区)都有自己的根目录 Linux系统, 也支持多个分区 Linux的分区 ...
- VisionPro · C# · 创建项目
将 VisionPro 引入 C# 项目程序中需要执行以下操作: 1.更改项目程序.NET框架: 2.添加编程引用: 3.添加界面设计控件引用: VisionPro 不同版本对应不同的 .NET 框架 ...
- Java 将HTML转为Word
本文以Java代码为例介绍如何实现将HTML文件转为Word文档(.docx..doc).在实际开发场景中可参考此方法来转换.下面详细方法及步骤. 在编辑代码前,请先在程序中导入Spire.Doc.j ...
- 多校联训 DP 专题
[UR #20]跳蚤电话 将加边变为加点,方案数为 \((n-1)!\) 除以一个数,\(dp\) 每种方案要除的数之和即可. 点击查看代码 #include<bits/stdc++.h> ...
- 零基础学Java(3)运算符
运算符 运算符用于连接值.Java提供了一组丰富的算术和逻辑运算符以及数学函数. 算术运算符 在Java中,使用算术运算符+.-.*./表示加.减.乘.除运算.当参与/运算的两个操作数都是整数时,表示 ...