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 如 ...
随机推荐
- 开发工具-Java SDK下载地址
更新记录 2022年6月14日 加入更多的下载地址. 2022年6月10日 完善标题. 下载地址: https://www.oracle.com/java/technologies/downloads ...
- 【Spring】AOP实现原理(一):AOP基础知识
AOP相关概念 在学习AOP实现原理之前,先了解下AOP相关基础知识. AOP面向切面编程,它可以通过预编译方式或者基于动态代理对我们编写的代码进行拦截(也叫增强处理),在方法执行前后可以做一些操作, ...
- Tensor的向量化
向量化操作是指可以在同一时间进行批量地并行计算,例如矩阵运算,以达到更好效率的一种方式. 尽量使用向量化直接对Tensor操作,避免低效率的for循环对元素逐个操作.
- Spring Security:用户和Spring应用之间的安全屏障
摘要:Spring Security是一个安全框架,作为Spring家族的一员. 本文分享自华为云社区<[云驻共创]深入浅出Spring Security>,作者:香菜聊游戏. 一.前言 ...
- 从0到1搭建一款Vue可配置视频播放器组件(Npm已发布)
前言 话不多说,这篇文章主要讲述如何从0到1搭建一款适用于Vue.js的自定义配置视频播放器.我们平时在PC端网站上观看视频时,会看到有很多丰富样式的视频播放器,而我们自己写的video标签样式却是那 ...
- django生成迁移文件和执行迁移的命令
生成迁移文件: python manage.py makemigrations #创建数据库迁移文件 执行迁移: python manage.py migrate # 根据数据库迁移文件生 ...
- UiPath图片操作截图的介绍和使用
一.截图(Take Screenshot)的介绍 截取指定的UI元素屏幕截图的一种活动,输出量仅支持图像变量(image) 二.Take Screenshot在UiPath中的使用 1. 打开设计器, ...
- Nginx防御CC攻击
CC攻击可以归为DDoS攻击的一种.他们之间都原理都是一样的,即发送大量的请求数据来导致服务器拒绝服务,是一种连接攻击.CC攻击又可分为代理CC攻击,和肉鸡CC攻击.代理CC攻击是黑客借助代理服务器生 ...
- Android 12(S) 图像显示系统 - HWC HAL 初始化与调用流程
必读: Android 12(S) 图像显示系统 - 开篇 接口定义 源码位置:/hardware/interfaces/graphics/composer/ 在源码目录下可以看到4个版本的HIDL ...
- NC24622 Brownie Slicing
NC24622 Brownie Slicing 题目 题目描述 Bessie has baked a rectangular brownie that can be thought of as an ...