前言

该文的前置篇为:

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.108232
setthread 15
dso

这里已经变成了string[]

用dumparray 00007f48e538a4b0 查看一下这个string[] 对象是啥?

看下第一个的string 对象的情况:

读取一下内存:

memory read -c 384 00007f48c3bc8f68

这里就基本确认问题了。

但是这样去定位问题,其实是有点慢的。而且发现,这个定位在cpu 倒是一个不错的选择,但是定位内存显得不那么合理。

因为cpu不高的情况,但是内存高的情况,这个时候肯定就是有很多碎片没有回收,上面查的情况是根据执行去判断的。

统计的方法定位问题是比较快的。

两个里面查看统计:

dumpheap -stat

第一个:

第二个:

发现这个system.string 两个都很大,且变多了,而DataRow 也不少。

但是这里涨的又不成比例,比如这里对象涨了几百,但是内存涨了200m。

这个时候可能就怀疑 大型对象堆 (LOH) 的问题了。

那么查一下大于85000字节的数据统计。

dumpheap -stat -min 85000

第一个:

第二个:

运行 dumpheap -stat -min 85000 -live。 此命令仅显示根于某处的对象。 在此示例中,只有正确的对象实例 string 位于 LOH 中。

-live 就是活跃的意思,也就是应用程序正在使用的,不会被GC的。

这里有4个,看下这4个是啥吧。

然后查看一个的内存:

这样就定位到了。

但是还得查看一下这个对象位置在哪? 怎么办呢?用SOS的命令:gcroot

这个是源代码内部的,看的不清楚。

使用-all

这样就直接定位到行了。

原因就是string+=string,等于String.Concat(System.String[]) 造成大量string 对象复制堆积。

下一节介绍procDump 和 dotnet-dump,procDump 这个挺好用的,dotnet-dump 更为方便。基本是必学的。

重新整理 .net core 实践篇 ———— linux上性能排查 [外篇]的更多相关文章

  1. 重新整理 .net core 实践篇 ———— linux上排查问题 [外篇]

    前言 简单介绍一下在排查问题.献给初学者. 该文的前置篇: https://www.cnblogs.com/aoximin/p/16838657.html 正文 什么是linux系统 linux 是基 ...

  2. 重新整理 .net core 实践篇 ———— linux上排查问题实用工具 [外篇]

    前言 介绍下面几个工具: Lldb createdump dotnet-dump dotnet-gcdump dotnet-symbol Procdump 该文的前置篇为: https://www.c ...

  3. 重新整理 .net core 实践篇 ———— linux 上线篇 [外篇]

    前言 简单整理一个linux 简单上线. 这个是该系列的外篇,该系列继续更新.献给刚学的人. 正文 安装实例 dotnet new webapp -n AspNetCoreDemo -o firstw ...

  4. 重新整理 .net core 实践篇————配置应用[一]

    前言 本来想整理到<<重新整理.net core 计1400篇>>里面去,但是后来一想,整理 .net core 实践篇 是偏于实践,故而分开. 因为是重新整理,那么就从配置开 ...

  5. Linux上性能异常定位以及性能监控

    引言:大多数的服务都是跑在Linux上的,Linux现在也已经到了一个很广泛的应用,但是仍然会有很多问题出现,我们就来讨论下我们性能监控的指标,性能监控无非就是从I/O,内存,CPU,TCP连接数,网 ...

  6. 重新整理 .net core 实践篇————依赖注入应用[二]

    前言 这里介绍一下.net core的依赖注入框架,其中其代码原理在我的另一个整理<<重新整理 1400篇>>中已经写了,故而专门整理应用这一块. 以下只是个人整理,如有问题, ...

  7. Node.js~在linux上的部署~外网不能访问node.js网站的解决方法

    这是上一篇node.js部署到linux上的后续文章,当我们安装完node.js之后,建立了sailsjs的网站,然后在外面电脑上无法访问这个网站,这个问题我们如何去解决? 解决思路: 查看linux ...

  8. 重新整理 .net core 实践篇————依赖注入应用之援军[四]

    前言 介绍第三方依赖注入框架Autofac,看看为我们解决什么问题. 下面介绍4个点: 命名注册 属性注册 aop 注入 子容器命名 正文 为什么我们需要使用第三方框架?第三方框架为我们做了什么?第三 ...

  9. 重新整理 .net core 实践篇—————服务与配置之间[十一二]

    前言 前面基本介绍了,官方对于asp .net core 设计配置和设计服务的框架的一些思路.看下服务和配置之间是如何联系的吧. 正文 服务: public interface ISelfServic ...

随机推荐

  1. Mysql 一主一从

    1. 主从原理 1.1 主从介绍 所谓 mysql 主从就是建立两个完全一样的数据库,其中一个为主要使用的数据库,另一个为次要的数据库,一般在企业中,存放比较重要的数据的数据库服务器需要配置主从,这样 ...

  2. 【python】pandas 索引操作

    选择.修改数据(单层索引) 推荐使用.at..iat..loc..iloc 操作 句法 结果 备注 选择列 df[col] Series 基于列名(列的标签),返回Series 用标签选择行 df.l ...

  3. flask-restful使用指南

    flask-restful是flask模块的一个扩展,能够快速构建restful风格的api.对于其他的扩展也有很高的兼容性. 安装flask_restful pip install flask_re ...

  4. XYX错误集

    (频数递减) # 数据范围:没开Long Long (*inf^2) # while 打成了 if ,if 打成了 while(*inf^2) # 换根DP:两个dfs调用错误 (*inf) # ZK ...

  5. 对Github指定类目的内容进行监控和推送

    很久之前看到HACK学习呀有一个Github 安全搬运工的系列文章,个人觉得很不错,想要在自己的公众号上也做这方面的内容,内容的编辑排版相对来说比较容易,这样问题就回归到Github安全内容的获取上 ...

  6. Knative部署应用以及应用的更新、应用的分流(二)

    1. 应用的更新 1.1 更新hello-example应用 1.更新应用的环境变量 可通过命令行的方式亦可以通过读取配置文件的方式,这里主要来看命令行的方式 [root@kn-server-mast ...

  7. Android平台Camera2数据如何对接RTMP推流到服务器

    1. Camera2架构 在Google 推出Android 5.0的时候, Android Camera API 版本升级到了API2(android.hardware.camera2), 之前使用 ...

  8. 变废为宝: 使用废旧手机实现实时监控方案(RTSP/RTMP方案)

    随着手机淘汰的速度越来越快,大多数手机功能性能很强劲就不再使用了,以大牛直播SDK现有方案为例,本文探讨下,如何用废旧手机实现实时监控方案(把手机当摄像头做监控之用): 本方案需要准备一个手机作为采集 ...

  9. 【UML分析、建模与设计】我在工作时遇到UML

    一.前言 UML分析.建模与设计 来自现实世界中的概念的抽象描述方法(摘取自<UML面向对象分析.建模与设计(第2版)>) 就我对UML分析与建模技术的认知,最早可追溯至2019年时的学习 ...

  10. PostgreSQL 大对象导出报错问题分析

    1.前言 在处理用户问题过程遇到一个问题.用户通过pg_dump导出 bytea 对象时,当行的大小超过 1G时,会报错: [v8r6c5b41@dbhost01 ~]$ sys_dump -t t1 ...