一:背景

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

  1. ArrayPool

  2. Http

  3. Socket

  4. 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 类库进行监控(大结局)的更多相关文章

  1. 解剖SQLSERVER 第十二篇 OrcaMDF 行压缩支持(译)

    解剖SQLSERVER 第十二篇   OrcaMDF 行压缩支持(译) http://improve.dk/orcamdf-row-compression-support/ 在这两个月的断断续续的开发 ...

  2. 第十二篇 SQL Server代理多服务器管理

    本篇文章是SQL Server代理系列的第十二篇,详细内容请参考原文 在这一系列的上一篇,我们查看了维护计划,一个维护计划可能会创建多个作业,多个计划.你还简单地看了SSIS子系统,并查看了维护计划作 ...

  3. 第十二篇 Integration Services:高级日志记录

    本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...

  4. Python之路【第十二篇】:JavaScrpt -暂无内容-待更新

    Python之路[第十二篇]:JavaScrpt -暂无内容-待更新

  5. Python开发【第二十二篇】:Web框架之Django【进阶】

    Python开发[第二十二篇]:Web框架之Django[进阶]   猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 ...

  6. 【译】第十二篇 Integration Services:高级日志记录

    本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...

  7. 【译】第十二篇 SQL Server代理多服务器管理

    本篇文章是SQL Server代理系列的第十二篇,详细内容请参考原文 在这一系列的上一篇,我们查看了维护计划,一个维护计划可能会创建多个作业,多个计划.你还简单地看了SSIS子系统,并查看了维护计划作 ...

  8. 专题开发十二:JEECG微云高速开发平台-基础用户权限

      专题开发十二:JEECG微云高速开发平台-基础用户权限 11.3.4自己定义button权限 Jeecg中.眼下button权限设置,是通过对平台自己封装的button标签(<t:dgFun ...

  9. 跟我学SpringCloud | 第十二篇:Spring Cloud Gateway初探

    SpringCloud系列教程 | 第十二篇:Spring Cloud Gateway初探 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如 ...

随机推荐

  1. JS:in语法

    1.应用于判断对象中是否有某一个成员 var obj = { name: "lili", age:10, gender:"girl" } console.log ...

  2. 关于使用koa 跨域问题你可能会遇到

    var cors = require('koa2-cors');// 跨域const allowOrigins = ["http://localhost:8080" // 需要跨域 ...

  3. WPF第三方控件,只能输入数字型数据

    话不多说,根据最近项目需求,为了减少输入验证等相关代码量,需要此控件 先上效果图 默认样式是这样,自己可以根据需求修改外形,但我更喜欢它自带的简洁版 有人可能会问怎么实现的呢?其实很简单,我们设置它的 ...

  4. Docker 与 K8S学习笔记(二十四)—— 工作负载的使用

    我们前面讲了很多关于Pod的使用,但是在实际应用中,我们不会去直接创建Pod,我们一般通过Kubernetes提供的工作负载(Deployment.DeamonSet.StatefulSet.Job等 ...

  5. linux系统调优工具

    系统调优思路 性能优化就是找到系统处理中的瓶颈以及去除这些的过程,性能优化其实是对 OS 各子系统达到一种平衡的定义.具体步骤如下: 1. 系统的运行状况: CPU -> MEM -> D ...

  6. jenkins配置自动执行sql脚本

    shell脚本: bigsql="select big_version,small_version from d0mstore.db_current_version order by big ...

  7. 令你瞠目结舌的 Python 代码技巧

    0. for-else 在 Python 中,else 不仅可以与 if 搭配使用,还可以与 for 结合. python答疑 咨询 学习交流群2:660193417### for x in rang ...

  8. docker 部署 minio

    1.下载镜像 docker pull minio/minio 2.启动 docker run -p 9000:9000 --name minio \ -d --restart=always \ -e ...

  9. idea中创建Java类时,自动在文件头中添加作者和创建时间

    在Settings中找到File and Code Templates 设置如下图所示. 效果展示:

  10. Linux YUM yum 命令详解

    Yum命令 常用yum命令列表 command is one of: * install package1 [package2] [...] * update [package1] [package2 ...