AOT漫谈专题(第二篇): 如何对C# AOT轻量级APM监控

news/2024/10/12 12:58:34

一:背景

1. 讲故事

上一篇我们聊到了如何调试.NET Native AOT 程序,这是研究一个未知领域知识的入口,这篇我们再来看下如何对 Native AOT 程序进行轻量级的APM监控,当然这里的轻量级更多的是对 AOT 中的coreclr内容的挖掘。

二:如何轻量级APM监控

1. 一个简单的例子

用一个不断的往内存中囤积数据的例子来演示吧,然后观察内存的趋势变化,参考代码如下:

internal class Program{public static List<string> list = new List<string>();static void Main(string[] args){Debugger.Break();Task.Run(() => { Run(); }).Wait();}static void Run(){for (int i = 0; i < 10000; i++){list.Add(string.Join(", ", Enumerable.Range(0, 20000)));Thread.Sleep(1);Console.WriteLine($"i={i}");}}}

这里要注意的是,AOT在 ilc 编译的过程中会采用摇树优化,言外之意就是 eventpipe跟踪组件 默认是不加入的,这个组件的源码在 src\native\eventpipe 目录下,主要是采用 ipc 的方式与接收者进行通讯。

如果有点懵的话可以简单的理解成这东西是托管版的ETW,msdn 上也给了一张对比图,参考如下:

说了这么多,言外之意就是要把 eventpipe 保留,方式就是在 csproj 中配置 EventSourceSupport =true 即可,参考如下:


<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><OutputType>Exe</OutputType><TargetFramework>net8.0</TargetFramework><ImplicitUsings>enable</ImplicitUsings><Nullable>enable</Nullable><PublishAot>true</PublishAot><InvariantGlobalization>true</InvariantGlobalization><EventSourceSupport>true</EventSourceSupport></PropertyGroup></Project>

接下来用 dotnet cli 进行 public 发布,参考如下:


dotnet publish -r win-x64 -c Debug  -o D:\testdump

程序启动好之后,接下来用dotnet-counter来洞察一下程序的托管堆,CPU 等各种指标,安装方式可以参考链接:https://learn.microsoft.com/zh-cn/dotnet/core/diagnostics/dotnet-counters


PS C:\Users\Administrator\Desktop> dotnet-counters monitor -n Example_21_1

从上图中我们确实也真真切切的看到了进程的各个指标,有些朋友可能会好奇,如果我没开 EventPipe还能挖到这些信息吗?这当然是可以的,不过这就需要你对 coreclr 底层有一定的了解度了。

2. 如何用windbg去挖

首先要知道的是sos 在 aot 中用不了的,但用不了不代表我们没办法,因为 sos 也是从 coreclr 中挖取的数据,那为什么我就不能自己去挖呢?

  1. 如何挖托管堆数据

sos 是在coreclr 的 gc_heap::generation_table 全局数组中挖取的数据,言外之意我也可以手工的去挖,然后拼凑成托管堆 ,参考如下:


0:009> dx -r1 (*((Example_21_1!WKS::generation (*)[5])0x7ff6fa99ca90))
(*((Example_21_1!WKS::generation (*)[5])0x7ff6fa99ca90))                 [Type: WKS::generation [5]][0]              [Type: WKS::generation][1]              [Type: WKS::generation][2]              [Type: WKS::generation][3]              [Type: WKS::generation][4]              [Type: WKS::generation]

这个数组就对应着 0代,1代,2代,LOH代,POH代 等数据。

  1. 如何知道当前机器的内存总量和CPU核心数

这个数据在dump分析过程中非常重要,它可以表示当前机器的robust能力,这些数据在 coreclr 的 g_SystemInfototal_physical_mem 全局变量中,参考如下:


0:009> x Example_21_1!WKS::gc_heap::total_physical_mem
00007ff6`fa9ac1b0 Example_21_1!WKS::gc_heap::total_physical_mem = 0x00000007`f7bbd0000:009> ? 0x00000007`f7bbd000 /0n1024/0n1024/0n1024
Evaluate expression: 31 = 00000000`0000001f0:009> dt Example_21_1!g_SystemInfo+0x000 dwNumberOfProcessors : 0xc+0x004 dwPageSize       : 0x1000+0x008 dwAllocationGranularity : 0x10000

可以看到当前机器的内存总量是 31G(32G),同时机器的CPU=12。

  1. 如何挖掘GC触发信息

捕获gc的触发可以有效的获取gc的触发代,触发原因,以及当前的托管堆静态和动态阈值情况,对我们洞察程序非常有帮助,那如何捕获呢?可以对gc触发的必经之路上下一个断点即可,比如:bp Example_21_1!WKS::gc_heap::gc1


0:010> bp Example_21_1!WKS::gc_heap::gc1 
0:010> g
Breakpoint 0 hit
Example_21_1!WKS::gc_heap::gc1:
00007ff7`e268cd20 488bc4          mov     rax,rsp
0:006> k 5# Child-SP          RetAddr               Call Site
00 0000001d`6c6febb8 00007ff7`e268ccac     Example_21_1!WKS::gc_heap::gc1 [D:\a\_work\1\s\src\coreclr\gc\gc.cpp @ 22250] 
01 0000001d`6c6febc0 00007ff7`e26742e0     Example_21_1!WKS::gc_heap::garbage_collect+0x77c [D:\a\_work\1\s\src\coreclr\gc\gc.cpp @ 24332] 
02 0000001d`6c6fec70 00007ff7`e26a5a8a     Example_21_1!WKS::GCHeap::GarbageCollectGeneration+0x300 [D:\a\_work\1\s\src\coreclr\gc\gc.cpp @ 50529] 
03 0000001d`6c6fecd0 00007ff7`e2672d84     Example_21_1!WKS::gc_heap::trigger_gc_for_alloc+0x5a [D:\a\_work\1\s\src\coreclr\gc\gc.cpp @ 18906] 
04 (Inline Function) --------`--------     Example_21_1!WKS::gc_heap::try_allocate_more_space+0x14e [D:\a\_work\1\s\src\coreclr\gc\gc.cpp @ 19048] 
...

接下来洞察内部的 gc_heap::settings 结构,信息如下:


0:006> dt Example_21_1!WKS::gc_heap::settings 00007ff7`e2c46fb0+0x000 gc_index         : Volatile<unsigned __int64>+0x008 condemned_generation : 0n0+0x00c promotion        : 0n0+0x010 compaction       : 0n1+0x014 loh_compaction   : 0n0+0x018 heap_expansion   : 0n0+0x01c concurrent       : 0+0x020 demotion         : 0n0+0x024 card_bundles     : 0n1+0x028 gen0_reduction_count : 0n0+0x02c should_lock_elevation : 0n0+0x030 elevation_locked_count : 0n0+0x034 elevation_reduced : 0n0+0x038 minimal_gc       : 0n0+0x03c reason           : 0 ( reason_alloc_soh )+0x040 pause_mode       : 1 ( pause_interactive )+0x044 found_finalizers : 0n0+0x048 background_p     : 0n0+0x04c b_state          : 0 ( bgc_not_in_process )+0x050 entry_memory_load : 0x30+0x058 entry_available_physical_mem : 0x00000004`1a660000+0x060 exit_memory_load : 00:006> dx -r1 (*((Example_21_1!Volatile<unsigned __int64> *)0x7ff7e2c46fb0))
(*((Example_21_1!Volatile<unsigned __int64> *)0x7ff7e2c46fb0))                 [Type: Volatile<unsigned __int64>][+0x000] m_val            : 0xd [Type: unsigned __int64]0:006> ? 0x41a660000/0n1024/0n1024/0n1024
Evaluate expression: 16 = 00000000`00000010

从上面的输出中可以看到当前GC的信息特别多:0xd次触发,并且是压缩式的回收,触发的是 0代,原因是代满了,当前机器还可使用的内存是 16G。

三:总结

虽然 .NET AOT 越来越成熟,但目前还是不能对 gcheap 进行sos级的分析,暂时只能手工的挖掘整理,不过我相信在 .NET10 或者 11 上应该能够得到完整的支持,毕竟这势不可挡!
图片名称

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/70619.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Windows平台软件打包工具(inno setup)的使用

目录Windows平台软件打包工具(inno setup)的使用inno setup中文版下载地址inno setup介绍软件特色Inno setup 打包教程 Windows平台软件打包工具(inno setup)的使用 inno setup中文版下载地址 正版下载:https://jrsoftware.org/isdl.php 中文版下载:链接: https://pan.bai…

Leetcode 1192. 查找集群内的关键连接

1.题目基本信息 1.1.题目描述 力扣数据中心有 n 台服务器,分别按从 0 到 n-1 的方式进行了编号。它们之间以 服务器到服务器 的形式相互连接组成了一个内部集群,连接是无向的。用 connections 表示集群网络,connections[i] = [a, b] 表示服务器 a 和 b 之间形成连接。任何服…

查看Github 发行版下载次数

比如我在Github上开源了软件,并且在Release里面发布了版本,但是Github release页面并没有下载统计次数的页面展示。下面列举的几个可以查看Release各个版本的下载量。1. https://somsubhra.github.io/github-release-stats/?username=hupo376787&repository=WeiboAlbumD…

K8S控制器理解-摘录自《云原生操作系统Kubernetes》

摘录自罗建龙等著的《云原生操作系统Kubernetes》,详细了解请查看原著。虽然控制器是Kubernetes比较复杂的组件,但是控制器这个概念本身,对我们来说并不陌生。我们生活中使用的洗衣机、冰箱、空调等,都要有控制器才能正常工作。 以下我们通过思考一个简易冰箱的设计过程,来…

ABAP面向对象视频课程 语法篇 共26节(SAP开发)

ABAP面向对象视频课程上线B站了,感兴趣的小伙伴可以去试看一下~ 课程地址:https://www.bilibili.com/cheese/play/ss33355?bsource=link_copy

【日记】强烈地意识到了:她对我而言,真的很重要

写在前面2164 字 | 情感内容 | 亲密关系 | HSP | 暴言注意正文最安静的一集。今天所有客户经理都出差去了。一楼只有我、柜面主管、前台和门卫四个人。两个小时没人说一句话。社恐天堂。工作上没什么好说的。中午明明人很少,但是食堂阿姨做了很多菜,就很奇怪。虽这么说,倒是…

ORCLE与MySQL的相互转化

1.情景展示 在实际开发中,不同的地方可能所需使用的数据库是不同的。 这就要求,我们开发的程序需要兼容不同的数据库,放到程序里面就是: 需要有不同类型的sqlMap文件。以既要兼容MySQL,也要兼容Oracle进行举例说明。 2.准备工作 第一步 根据已经写好的一套sql进行复制,然…

【解决方案】Sublime Text 4 按下 Esc 键后无法输入任何内容

在最后编辑博客内容时,我的 Sublime 版本为 4180。我基本用 Sublime Text 4 替代了系统自带的 Notepad,我用它编辑任何东西(除了代码,手动狗头)。 开始我怀疑是 Package Control 安装了过多依赖导致的兼容性问题,但由于 Sublime 多次更新,我的 Package Control 再次从命…