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

news2024/10/12 14:01:20

一:背景

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`f7bbd000

0:009> ? 0x00000007`f7bbd000 /0n1024/0n1024/0n1024
Evaluate expression: 31 = 00000000`0000001f

0: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 : 0

0: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.coloradmin.cn/o/2208075.html

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

相关文章

面试官最喜欢问的28道ZooKeeper面试题

前言 ZooKeeper 是一个分布式的&#xff0c;开放源码的分布式应用程序协调服务。它是一个为分布式应用提供一致性服务的软件&#xff0c;提供的功能包括&#xff1a;配置维护、域名服务、分布式同步、组服务等。 ZooKeeper 的目标就是封装好复杂易出错的关键服务&#xff0c;…

再也不怕面试官问我几百亿ip相关的问题了

首先要明确这一类的问题都是海量那个数据类型的问题&#xff0c;对于海量数据我们一般采用分而治之的思路去解决&#xff0c;考官考察的就是你有没有处理海量数据的经验。总结几个常见的海量数据相关的面试&#xff0c;供参考。 有一个存放10GB的ip地址文件&#xff0c;每行一…

2024年【安全生产监管人员】免费试题及安全生产监管人员模拟试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年安全生产监管人员免费试题为正在备考安全生产监管人员操作证的学员准备的理论考试专题&#xff0c;每个月更新的安全生产监管人员模拟试题祝您顺利通过安全生产监管人员考试。 1、【单选题】()以上地方人民政府…

基于SSM的民宿预订系统的设计与实现

文未可获取一份本项目的java源码和数据库参考。 一、毕业设计&#xff08;论文&#xff09;选题的目的和意义 由于现代人经济水平的不断提高&#xff0c;出门旅游已经成为人们放松和休息的一种生活方式。而出门在外&#xff0c;住宿也是首要问题&#xff0c;相比于传统的酒店…

五子棋项目自动化测试

目录 一、五子棋项目介绍 二、编写Web测试用例 三、自动化测试脚本开发 1、引入依赖 2、设计框架 3、Utils 4、LoginPage 5、RegisterPage 6、MatchPage 7、RunTest类 8、运行程序 一、五子棋项目介绍 五子棋项目是基于 WebSocket 实现的多人在线对战系统&#xff0…

【优选算法】(第三十六篇)

目录 ⼆叉树的锯⻮形层序遍历&#xff08;medium&#xff09; 题目解析 讲解算法原理 编写代码 ⼆叉树的最⼤宽度&#xff08;medium&#xff09; 题目解析 讲解算法原理 编写代码 ⼆叉树的锯⻮形层序遍历&#xff08;medium&#xff09; 题目解析 1.题目链接&#xf…

【高中生讲机器学习】21. 隐马尔可夫模型好难?看过来!(下篇)

创建时间&#xff1a;2024-10-09 首发时间&#xff1a;2024-10-12 最后编辑时间&#xff1a;2024-10-12 作者&#xff1a;Geeker_LStar 你好呀~这里是 Geeker_LStar 的人工智能学习专栏&#xff0c;很高兴遇见你~ 我是 Geeker_LStar&#xff0c;一名高一学生&#xff0c;热爱计…

SpringBoot购物推荐网站:设计与实现的最佳实践

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常适…

『深度分析』Kimi版o1来了!Kimi探索版全面解读!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;专注于分享AI全维度知识&#xff0c;包括但不限于AI科普&#xff0c;AI工…

28幅高清修复的英文版中国地图

我们在《183幅值得珍藏的全国地质图集》和《55幅值得珍藏的水文地质图集》两文中&#xff0c;为你分享过精美的全国地质图和水文地质图。 现在我们整理了28幅英文版中国地图&#xff0c;并经过高清修复后分享给大家&#xff0c;你可以在文末查看该数据的领取方法。 28幅英文版…

Channel模块 --- 管理套接字事件

目录 设计思想 实现 设计思想 Channel模块是用于对一个描述符所需要监控的事件以及事件触发之后要执行的回调函数进行管理的 具体来说&#xff0c;它里面会保存该文件描述符所监控的事件&#xff0c;该文件描述符所就绪的事件&#xff0c;以及该描述符的各种事件的处理回调…

4 机器学习之归纳偏好

通过学习得到的模型对应了假设空间中的一个假设。于是&#xff0c;图1.2的西瓜版本空间给我们带来一个麻烦&#xff1a;现在有三个与训练集一致的假设&#xff0c;但与它们对应的模型在面临新样本的时候&#xff0c;却会产生不同的输出。例如&#xff0c;对&#xff08;色泽青绿…

java算法oj(3)栈和队列

目录 1.前言 2.正文 2.1基础操作 2.2用栈实现队列 2.2.1题目 2.2.2示例 2.2.3代码 2.3用队列实现栈 2.3.1题目 2.3.2示例 2.3.3代码 2.4最小栈 2.4.1题目 2.4.2示例 2.4.3代码 3.小结 1.前言 哈喽大家好吖&#xff0c;今天来分享几道栈与队列的算法题&#…

三、AOP

文章目录 1. AOP&#xff08;概念&#xff09;2. AOP&#xff08;底层原理&#xff09;2.1 AOP 底层使用动态代理2.2 AOP&#xff08;JDK动态代理&#xff09; 3. AOP&#xff08;术语&#xff09;3.1 连接点3.2 切入点3.3 通知&#xff08;增强&#xff09;3.4 切面 4. AOP操作…

数据丢失不再怕!四款数磁盘数据恢复据恢复工具实测心得

在办公室行政的工作中&#xff0c;数据恢复工具是我们不可或缺的帮手。无论是不小心删除了重要文件&#xff0c;还是硬盘突然罢工&#xff0c;这些工具总能在关键时刻帮我们力挽狂澜。今天&#xff0c;我就来分享一下我使用福昕数据恢复、转转大师数据恢复、超级兔子数据恢复和…

MySQL 【数字】函数大全(二)

MODPIPOWPOWERRANDROUNDSIGNSQRTTRUNCATE 1、MOD MOD(number1, number2) &#xff1a;返回一个数字除以另一个数字的余数。 语法&#xff1a; 1、MOD(number1, number2) 2、number1 MOD number2 3、number1 % number2 number1&#xff1a;被除数。 number2&#xff1a;除数。…

Qt学习系列之设计模式的小记录

Qt学习系列之设计模式的小记录 前言Qt中的设计模式使用情况数据模型视图组建代理 小tips虚函数&#xff1a;基类的不同具体使用界面设计后台显示 报错解决 总结 前言 在软件设计师中的设计模式有提到设计模式有三种类型&#xff1a; 创建型&#xff1a;工厂方法模式、抽象工厂…

上海AI实验室CVT-Occ时间融合利用视差搜索刷新occ3DWaymo SOTA

上海AI实验室提出CVT-Occ&#xff1a;通过时间融合利用视差搜索刷新occ3D-Waymo SOTA Abstract 基于视觉的3D占据预测由于单目视觉在深度估计上的固有局限性而面临显著挑战。本文介绍了CVT-Occ&#xff0c;一种新颖的方法&#xff0c;通过时间上的体素几何对应进行时间融合&a…

华为OD机试 - 最快到达医院的方法(Python/JS/C/C++ 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…

欧洲气象局开源数据如何通过大模型预测未来天气

气象预测依赖于全球各地的观测数据、复杂的数学模型和高性能计算资源。欧洲气象局&#xff08;ECMWF&#xff0c;European Centre for Medium-Range Weather Forecasts&#xff09;作为世界领先的气象预报机构&#xff0c;不仅提供精确的天气预报服务&#xff0c;还向公众和科研…