前言该文的前置篇为:
https://www.cnblogs.com/aoximin/p/16839830.html
本文介绍性能排查 。
正文上一节是出现错误了 , 如何去排查具体问题 。
这一节介绍一下性能排查 。
还是上文的例子作为演示:https://buggyambfiles.blob.core.windows.net/bin/buggyamb_v1.1.zip
项目地址:https://github.com/ahmetmithat/buggyamb
本文实验的还是lldb 和 sos 。
对比一下cpu 情况 。
实验实施条件:
文章插图
请求前:
文章插图
点击请求后:
文章插图
这样对比还是很大的哈 。
那么我们来看下啥子情况吧 。
查看进程名:
文章插图
那么当cpu 高的时候进行抓取,一般抓取两个,两个间隔10秒左右 。
为什么抓取两个呢? 因为好对比作用 , 更好定位,这个多实验实验就清楚了 。
抓取命令:
/usr/share/dotnet/shared/Microsoft.NETCore.App/3.1.30/createdump 108232 -f /tmp/coredump.manual.1.%d/usr/share/dotnet/shared/Microsoft.NETCore.App/3.1.30/createdump 108232 -f /tmp/coredump.manual.2.%d
两个命令间隔10秒 。我们知道这个createdump 是 dotcore runtime 自带的 。
那么怎么知道他的位置呢?
文章插图
这样可以查找到位置 。
文章插图
可以看到10秒后内存升高了 。
那么就可以上一章的内容了 , 进入lldb 。
lldb --core coredump.manual.1.108232
然后查看线程:
文章插图
看这个线程,发现和其他GC mode 不一样 。
那么就有一个东西需要科普了,分别是cooperative 和 preemptive 。
如果线程的 GC 模式设置为 “抢占”,则表示 GC 可以随时挂起此线程 。相比之下 , 协作模式意味着 GC 必须等待线程切换到抢占模式,然后才能挂起它 。当线程运行托管代码时,它处于协作模式 。
这句话什么意思呢? 就是说这个线程在占用cpu的意思 。那么cpu 高就应该看这个东西了 。setthread 14 然后切到这个线程 。这里就不解释了,都是上一章的东西 。
然后调用一下clrstack 。
文章插图
然后来看一下干了什么?
文章插图
感觉是在做字符串拼接啊 。
那么这个时候是会造成cpu高和内存高的,那么要证明自己的猜想 。
使用dso 查看一下 。
Displays all managed objects found within the bounds of the current stack.
文章插图
看下这个string,为什么看这个呢?因为这个string,和System.Data.DataRow 比较近,这个可以学习汇编可能跟容易理解 。
文章插图
查看了一下这个倒是有100m 。
读取一下内存,看下里面是什么?
文章插图
那么我们知道,第二次转储文件的时候内存是上述了的 。
那么同样的操作在第二个里面执行:
lldb --core /tmp/coredump.manual.2.108232setthread 15dso
文章插图
这里已经变成了string[]
用dumparray 00007f48e538a4b0 查看一下这个string[] 对象是啥?
文章插图
看下第一个的string 对象的情况:
文章插图
读取一下内存:
memory read -c 384 00007f48c3bc8f68
文章插图
这里就基本确认问题了 。
但是这样去定位问题 , 其实是有点慢的 。而且发现,这个定位在cpu 倒是一个不错的选择,但是定位内存显得不那么合理 。
因为cpu不高的情况,但是内存高的情况,这个时候肯定就是有很多碎片没有回收,上面查的情况是根据执行去判断的 。
推荐阅读
- 在 .NET 7上使用 WASM 和 WASI
- 重新整理 .net core 实践篇 ———— linux上排查问题实用工具 [外篇]
- .NET 7 中 LINQ 的疯狂性能提升
- 两种 .Net Core 3.0 对 MongoDB 的多条件查询操作
- 螃蟹断掉的腿,还能重新长出来吗?
- .NET性能优化-复用StringBuilder
- .net 温故知新:【8】.NET 中的配置从xml转向json
- 来啦来啦|开源 * 安全 * 赋能 - .NET Conf China
- 如何在.NET程序崩溃时自动创建Dump?
- .NET Conf 2022 – 11 月 8 日至 10 日