当前位置: 首页 > news >正文

记一次 .NET某设备监控自动化系统 CPU爆高分析

一:背景

1. 讲故事

先说一下题外话,一个监控别人系统运行状态的程序,结果自己出问题了,有时候想一想还是挺讽刺的,哈哈,开个玩笑,我们回到正题,前些天有位朋友找到我,说他们的系统会偶发性CPU爆高,CPU上去了就下不来了,让我帮忙看一下怎么回事,而且自己也分析过了,没找到哪里有问题,写监控的都是高手,给我的第一感觉就是这个dump可能解决起来不容易,不管怎么说,有了dump就开干吧!

二:WinDbg 分析

1. CPU真的爆高吗

作为调试人,第一准则就是不要轻信任何人透露给你的信息,因为人家在这块是一个小白,往往他的信息会把你带偏,我们只相信数据即可,切记!!! 所以我们先用 !tp 观察下CPU使用率。


0:198> !tp
CPU utilization: 100%
Worker Thread: Total: 197 Running: 42 Idle: 154 MaxLimit: 32767 MinLimit: 8
Work Request in Queue: 0
--------------------------------------
Number of Timers: 0
--------------------------------------
Completion Port Thread:Total: 10 Free: 5 MaxFree: 16 CurrentLimit: 10 MaxLimit: 1000 MinLimit: 8

从卦中信息看当前 CPU=100%,还是蛮惨的,那到底谁在吃CPU资源呢?根据经验先查一下是不是触发了2代GC,接下来用 !t 观察下是否有GC标记。


0:198> !t
ThreadCount:      214
UnstartedThread:  0
BackgroundThread: 211
PendingThread:    0
DeadThread:       1
Hosted Runtime:   noLock  ID OSID ThreadOBJ           State GC Mode     GC Alloc Context                  Domain           Count Apt Exception0    1 276f0 000002789526b5f0    2a020 Preemptive  0000000000000000:0000000000000000 000002789525e840 0     MTA 2    2 25e5c 0000027895296d00    2b220 Preemptive  0000000000000000:0000000000000000 000002789525e840 0     MTA (Finalizer) 3    3 260e8 00000278ae35f0c0  202b020 Preemptive  0000000000000000:0000000000000000 000002789525e840 0     MTA ...169 2113 10c20 00000278c26766c0  1029220 Preemptive  00000278B5D7D188:00000278B5D7D188 000002789525e840 1     MTA (GC) (Threadpool Worker) xxxException 00000278b5d46ce0...

尼玛从卦中的 (GC) 来看,还真的触发了GC,接下来的研究方向就是洞察下是不是CPU爆高的祸首。

2. GC触发导致的吗

要寻找这个问题的答案,首先就是看下这次GC是不是 FullGC 即可,可以切到 169 号线程,观察下线程栈。


0:169> k 10# Child-SP          RetAddr               Call Site
00 000000c4`36ffb798 00007ffc`d5f14313     ntdll!NtWaitForSingleObject+0x14
01 000000c4`36ffb7a0 00007ffc`c927cb27     KERNELBASE!WaitForSingleObjectEx+0x93
02 000000c4`36ffb840 00007ffc`c927cadf     clr!CLREventWaitHelper2+0x3c
03 000000c4`36ffb880 00007ffc`c927ca5c     clr!CLREventWaitHelper+0x1f
04 000000c4`36ffb8e0 00007ffc`c926bd32     clr!CLREventBase::WaitEx+0x7c
05 000000c4`36ffb970 00007ffc`c9269bc4     clr!ThreadSuspend::SuspendRuntime+0x32c
06 000000c4`36ffba60 00007ffc`c91814e3     clr!ThreadSuspend::SuspendEE+0x128
07 000000c4`36ffbb60 00007ffc`c9185f51     clr!WKS::GCHeap::GarbageCollectGeneration+0xb7
08 000000c4`36ffbbc0 00007ffc`c9260f56     clr!WKS::gc_heap::trigger_gc_for_alloc+0x2d
09 000000c4`36ffbc00 00007ffc`c6b0f7e7     clr!JIT_NewArr1+0xa97
0a 000000c4`36ffc030 00007ffc`6a388270     mscorlib_ni!System.String.ToCharArray+0x27 [f:\dd\ndp\clr\src\BCL\system\string.cs @ 758] 
0b 000000c4`36ffc080 00007ffc`6a3880ed     0x00007ffc`6a388270
0c 000000c4`36ffc100 00007ffc`6a56056d     0x00007ffc`6a3880ed
0d 000000c4`36ffc150 00007ffc`6a3cd749     0x00007ffc`6a56056d
0e 000000c4`36ffc1b0 00007ffc`c911989d     0x00007ffc`6a3cd749
0f 000000c4`36ffc220 00007ffc`c9119764     clr!ExceptionTracker::CallHandler+0xfd

从卦中看此时的GC还处于早期的 SuspendEE 阶段,无法获取内部的 settings 结构,这就比较麻烦了,那怎么办呢?只能看看 GarbageCollectGeneration 的第一个参数有没有保存在栈中,要是没有就惨了。。。方法签名如下:


size_t
GCHeap::GarbageCollectGeneration (unsigned int gen, gc_reason reason)
{}

根据 x64调用协定,gen是保存在 rdx 寄存器里,接下来观察汇编代码。


0:000> uf 00007ffc`c91814e3
clr!WKS::GCHeap::GarbageCollectGeneration:
00007ffc`c918142c 48895c2418      mov     qword ptr [rsp+18h],rbx
00007ffc`c9181431 89542410        mov     dword ptr [rsp+10h],edx
00007ffc`c9181435 48894c2408      mov     qword ptr [rsp+8],rcx
00007ffc`c918143a 55              push    rbp
00007ffc`c918143b 56              push    rsi
00007ffc`c918143c 57              push    rdi
00007ffc`c918143d 4154            push    r12
00007ffc`c918143f 4155            push    r13
00007ffc`c9181441 4156            push    r14
00007ffc`c9181443 4157            push    r15
...0:169> dd 000000c4`36ffbbc0-0x8+0x10 L1
000000c4`36ffbbc8  00000000

从卦中看,谢天谢地,edx保存在 rsp+10h 的位置,通过dp观察内存地址的值发现是0,也就表示当前是 0 代GC,这种smallgc 经常触发是很正常的,并不是我们CPU爆高的诱因,接下来就陷入迷茫了。。。

3. 路在何方

撞了南墙之后得要看看其他路子,其实刚才用 !t 观察线程列表的时候我就注意到一个特征,那就是很多线程上挂了异常,截图如下:

从卦中看此时有19个线程在抛 xxxResultException 异常,做过开发的朋友都知道,如果频繁的抛异常是很耗CPU资源的,因为它要设计到用户态内核态的切换,如果有 19 个线程一起抛异常,那绝对是一个灾难。。。

有些朋友说我cpu猛一点是不是就可以了,哈哈,理论上是可以的,可以用 !cpuid 观察下这台机器的cpu核心数。


0:169> !cpuid
CP  F/M/S  Manufacturer     MHz0  6,167,1  <unavailable>   34081  6,167,1  <unavailable>   34082  6,167,1  <unavailable>   34083  6,167,1  <unavailable>   34084  6,167,1  <unavailable>   34085  6,167,1  <unavailable>   34086  6,167,1  <unavailable>   34087  6,167,1  <unavailable>   3408

从证据链的完整性上来说,其实这里还需要再做一个验证,就是19个线程抛异常不代表他们的并发性,言外之意就是能不能再找一些其他证据,怎么找其他证据呢?

做C#开发的朋友应该知道,Exception 属于引用类型,如果密集抛了很多异常,那托管堆上自然就有很多,直到GC回收,所以我们观察下这个时间差即可,使用 !wdae 命令,这里为了隐私性我就模糊了哈。


0:169> !wdae384 of Type: xxxResultException 000002789fdb6478 000002789fdb69b0 000002789fdb9848
Message: xxxFailed
Inner Exception: (none)
Stack:
IP               Function
00007ffc6a269861 xxx.ChannelAsyncOperation`1[[System.Int32, mscorlib]].End(Int32, Boolean)
...411 of Type: xxxResultException 000002789fdb6e90 000002789fdb7090 000002789fdb72a8
Message: xxxClosed
Inner Exception: (none)
Stack:
IP               Function
00007ffc6a269861 xxx.ChannelAsyncOperation`1[[System.Int32, mscorlib]].End(Int32, Boolean)
...
808 Exceptions in 12 unique type/stack combinations (duplicate types in similar stacks may be rethrows)

从卦中看当前抛了808个异常,大多是和channel通信有关,结合16个线程并发抛,这就稳了,看样子cpu爆高期间就是由于高频的抛异常所致,分析出这些信息之后,就是告诉朋友把这些异常给解决掉即可。

三:总结

CPU爆高的诱因非常多,高频的抛异常就属于其中一例,其实这种通信时发生了突发异常正是 Polly 这种 弹性和瞬态故障处理库 大显身手的地方。

相关文章:

记一次 .NET某设备监控自动化系统 CPU爆高分析

一&#xff1a;背景 1. 讲故事 先说一下题外话&#xff0c;一个监控别人系统运行状态的程序&#xff0c;结果自己出问题了&#xff0c;有时候想一想还是挺讽刺的&#xff0c;哈哈&#xff0c;开个玩笑&#xff0c;我们回到正题&#xff0c;前些天有位朋友找到我&#xff0c;说…...

大数据与云计算

目录 一、大数据时代二、云计算——大数据的计算三、云计算发展现状四、云计算实现机制五、云计算压倒性的成本优势 一、大数据时代 我们先来看看百度关于 “大数据”&#xff08;Big Data&#xff09;的搜索指数。 可以看出&#xff0c;“大数据” 这个词是从2012年才引起关注…...

一. 并行处理与GPU体系架构-并行处理简介

目录 前言0. 简述1. 串行处理与并行处理的区别2. 并行执行3. 容易混淆的几个概念4. 常见的并行处理总结参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习下课程第一章——并行处…...

vb机试考试成绩分析与统计,设计与实现(高数概率统计)-141-(代码+程序说明)

转载地址http://www.3q2008.com/soft/search.asp?keyword141 前言: 为何口出狂言,作任何VB和ASP的系统, 这个就是很好的一个证明 :) 又有些狂了... 数据库操作谁都会,接触的多了也没什么难的,VB编程难在哪?算法上,这个是一个算法题的毕业设计,里面涉及到对试卷的 平均分,最…...

Arm MMU深度解读

文章目录 一、MMU概念介绍二、虚拟地址空间和物理地址空间2.1、(虚拟/物理)地址空间的范围2.2、物理地址空间有效位(范围) 三、Translation regimes四、地址翻译/几级页表&#xff1f;4.1、思考&#xff1a;页表到底有几级&#xff1f;4.2、以4KB granule为例&#xff0c;页表的…...

2024 年 AI 辅助研发趋势

在2024年&#xff0c;AI辅助研发的应用趋势将非常广泛。举个例子&#xff0c;比如在医疗健康领域&#xff0c;AI将深度参与新药研发、早期癌症研究以及辅助诊断等&#xff0c;助力医疗技术的突破。同时&#xff0c;在农业领域&#xff0c;AI也将通过无人机、智能装备等方式&…...

聊聊pytho中的函数

Python中的函数 一、Python中函数的作用与使用步骤 1、为什么需要函数 在Python实际开发中&#xff0c;我们使用函数的目的只有一个“让我们的代码可以被重复使用” 函数的作用有两个&#xff1a; ① 代码重用&#xff08;代码重复使用&#xff09; ② 模块化编程&#x…...

Python中starmap有什么用的?

目录 前言 starmap函数的作用 starmap函数的用法 starmap函数的示例 1. 对每个元组元素进行求和 2. 对每个元组元素进行乘积 实际应用场景 1. 批量处理函数参数 2. 并行处理任务 3. 批量更新数据库 总结 前言 在Python中&#xff0c; starmap 是一个非常有用的函数&…...

面向切面编程 AOP

提示&#xff1a;主要内容参考动力节点老杜的Spring6讲义。 面向切面编程 AOP 一、AOP介绍二、AOP的七大术语三、切点表达式 IoC使软件组件松耦合。AOP让你能够捕捉系统中经常使用的功能&#xff0c;把它转化成组件。AOP&#xff08;Aspect Oriented Programming&#xff09;&a…...

POS 之 奖励机制

为什么需要有奖惩机制 如果没有奖励&#xff0c;就不会有节点参与POS&#xff0c;运营节点有成本&#xff0c;而奖励正是让运营者获利的方式 如果没有惩罚&#xff0c;网络上会充斥着很多无效节点&#xff0c;会扰乱甚至破坏网络 所有奖励和惩罚在每个 Epoch 实施一次 奖励 什…...

Unity类银河恶魔城学习记录9-7 p88 Crystal instead of Clone源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Blackhole_Skill_Controller.cs using System.Collections; using System…...

导出RWKV模型为onnx

测试模型&#xff1a; https://huggingface.co/RWKV/rwkv-5-world-3b 导出前对modeling_rwkv5.py进行一个修改&#xff1a; # out out.reshape(B * T, H * S) out out.reshape(B * T, H * S, 1) # <<--- modified out F.group_norm(out, nu…...

【LeetCode】整数转罗马数字 C语言 | 此刻,已成艺术(bushi)

Problem: 12. 整数转罗马数字 文章目录 思路解题方法复杂度Code 思路 暴力破解 转换 解题方法 由思路可知 复杂度 时间复杂度: O ( n ) O(n) O(n) 空间复杂度: O ( 1 ) O(1) O(1) Code char* intToRoman(int num) {char *s (char*)malloc(sizeof(char)*4000), *p s;while(…...

移动App开发常见的三种模式:原生应用、H5移动应用、混合模式应用

引言 在移动应用市场的迅猛发展中&#xff0c;移动App开发正日益成为技术创新和用户体验提升的焦点。对于开发者而言&#xff0c;选择适合自己项目的开发模式成为至关重要的决策。本文将探究移动App开发的三种常见模式&#xff1a;原生应用、H5移动应用和混合模式应用。这三种…...

k8s Secret配置资源,ConfigMap 存储配置信资源管理详解

目录 一、Secret 概念 三种Secret类型 pod三种使用secret的方式 应用场景&#xff1a;凭据&#xff1a; 二、 示例 2.1、用kubectl create secret命令创建 Secret 创建Secret&#xff1a; 查看Secret列表&#xff1a; 描述Secret&#xff1a; 2.2、用 base64 编码&…...

POS 之 最终确定性

Gasper Casper 是一种能将特定区块更新为 最终确定 状态的机制&#xff0c;使网络的新加入者确信他们正在同步规范链。当区块链出现多个分叉时&#xff0c;分叉选择算法使用累计投票来确保节点可以轻松选择正确的分叉。 最终确定性 最终确定性是某些区块的属性&#xff0c;意味…...

Vue快速开发一个主页

前言 这里讲述我们如何快速利用Vue脚手架快速搭建一个主页。 页面布局 el-container / el-header / el-aside / el-main&#xff1a;https://element.eleme.cn/#/zh-CN/component/container <el-container><el-header style"background-color: #4c535a"…...

Java SE入门及基础(33)

final 修饰符 1. 应用范围 final 修饰符应该使用在类、变量以及方法上 2. final 修饰类 Note that you can also declare an entire class final. A class that is declared final cannot be subclassed. This is particularly useful, for example, when creating an imm…...

ChatGPT逐步进入留学圈但并不能解决留学规划的问题

2022 年底&#xff0c;一个能像人类一样对话的AI软件ChatGPT&#xff0c;在5天内突破一百万用户&#xff0c;风靡全球&#xff0c;如今用户已达1.8亿。 四个月后&#xff0c;ChatGPT进化为GPT4版本。该版本逻辑、数学推理能力卓越。拿留美标准化考试举例&#xff0c;GPT4能够在…...

WebGL之灯光使用解析

在使用灯光之前&#xff0c;首先我们需要了解&#xff0c;与定义更广泛的 OpenGL 不同&#xff0c;WebGL 并没有继承 OpenGL 中灯光的支持。所以你只能由自己完全得控制灯光。幸运得是&#xff0c;这也并不是很难&#xff0c;本文接下来就会介绍完成灯光的基础。 在 3D 空间中…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...

Leetcode33( 搜索旋转排序数组)

题目表述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

es6+和css3新增的特性有哪些

一&#xff1a;ECMAScript 新特性&#xff08;ES6&#xff09; ES6 (2015) - 革命性更新 1&#xff0c;记住的方法&#xff0c;从一个方法里面用到了哪些技术 1&#xff0c;let /const块级作用域声明2&#xff0c;**默认参数**&#xff1a;函数参数可以设置默认值。3&#x…...