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

【经验分享】日常开发中的故障排查经验分享(一)

目录

  • 简介
  • CPU飙高问题
    • 1、使用JVM命令排查CPU飙升100%问题
    • 2、使用Arthas的方式定位CPU飙升问题
    • 3、Java项目导致CPU飙升的原因有哪些?如何解决?
  • OOM问题(内存溢出)
    • 1、如何定位OOM问题?
    • 2、OOM问题产生原因
  • 死锁问题的定位
  • 频繁Full GC问题
    • 1、频繁FullGC会导致哪些问题
    • 2、如何排查
    • 3、导致频繁FullGC的原因
  • 内存泄露问题的排查
  • 磁盘空间不足,如何排查Linux中的大文件位置
  • 尾声

简介

众所周知,咱们程序员在日常工作中肯定少不了会碰到系统故障、系统缓慢等问题,该笔记是我在工作中对一些OOM、CPU飙高、内存泄露等问题的排查笔记,现在分享出来,因为平时开发中我就是根据这些步骤进行排查的,没有附图,不喜勿喷。

CPU飙高问题

1、使用JVM命令排查CPU飙升100%问题

  • 第一步:查看系统进程CPU使用率,首先使用【top】命令列出系统各个进程的资源占用,查看是哪个进程的CPU不对劲,看 %CPU 这个数值,然后找到对应的进程ID号。

  • 第二步:查看当前进程号的线程CPU使用率,使用【top -Hp 进程ID】命令查看第一步查询出来的进程ID内的线程CPU使用情况。

  • 第三步:找到CPU使用率高的线程并将PID转化为十六进制,将这个PID转化为十六进制【printf ‘0x%x’ PID】。

  • 第四步:输出当前进程内的该线程的堆栈信息,有两种方式,

    • 一种是使用jstack命令将之前的那个CPU高的进程输出到一个txt文件中【jstack 1677 > 1.txt】,然后使用vim或者grep根据十六进制去搜索。
    • 另外一种就是直接使用【jstack 进程ID | grep 16进制的线程PID -A20】这个命令直接输出后20行,找到对应代码位置。
  • 最后定位到具体业务代码的位置,我们去找到对应代码修改就行了

2、使用Arthas的方式定位CPU飙升问题

  • 第一步:需要去下载arthas的jar包:wget https://arthas.aliyun.com/arthas-boot.jar

  • 第二步:启动arthas:java -jar arthas-boot.jar

  • 第三步:其实启动的时候就显示了CPU高的类了,但是我们可以通过命令查看:
    查看系统整体运行情况:dashboard
    查看最繁忙的线程【可以显示具体代码位置】:thread -n 1
    查看繁忙的线程具体的代码:jad 【上面查询出来的包名+类名】
    找到代码位置后,根据实际业务场景去做修改就行了。

3、Java项目导致CPU飙升的原因有哪些?如何解决?

CPU飙高的原因:

1、代码中存在大量的循环、递归或者重复计算等操作,导致程序运行时消耗大量的CPU资源。
2、代码中需要处理大量的数据,如果数据量过大或者处理不当,会导致CPU占用过高。
3、频繁的IO操作,代码中涉及到频繁访问数据库、频繁读写文件等操作,由于IO操作比较耗时,导致CPU占用过高。
4、代码中创建大量线程并处于长时间忙碌状态,会导致CPU占用过高。
5、多线程之间互相竞争同一资源,导致CPU不断切换线程从而消耗大量资源,会导致CPU占用过高。
6、JVM问题:配置不当或者性能问题导致CPU过高。
7、内存泄露也有可能导致CPU飙高。内存泄露的程序,JVM频繁进行FullGC尝试释放内存空间,进而会导致CPU飙升,内存泄露过多,造成可回收内存不足,程序申请内存失败,结果就是内存溢出。

如何解决:

  • 优化代码逻辑,尽量减少重复计算和不必要的循环
  • 合理处理大量数据,可以使用分页或者分批处理的方式。
  • 检查并发处理的线程数量,合理控制线程的创建和销毁。
  • 对JVM进行适当的配置和调优,如调整堆大小、垃圾回收策略等。

还是要根据具体的业务场景来进行优化。

OOM问题(内存溢出)

1、如何定位OOM问题?

一般出现OOM问题,java.lang.OutOfMemoryError:Java heap space或者其他,我们都是通过dump文件去定位问题。

方式一(生产环境经常使用的方式):
我们工作里面都是在启动脚本里面提前加入:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/logs/dump/
这个配置信息来提前预防,当出现OOM问题时,会将当前内存输出一个dump文件放入到指定的目录下(我这里是放到/logs/dump/目录下),然后将文件下载下来以后,通过MAT或者JProfile或者visualvm工具加载dump文件进行调试,查看最多跟业务有关的对象,然后找到GCRoot,查看线程栈的输出定位到具体代码位置。

方式二:使用命令主动导出
需要导出dump文件:【jmap -dump:format=b,file=1.hprof PID】或者通过Arthas工具;

2、OOM问题产生原因

  • 一次性申请了太多的对象:比如说做一些列表的查询,一次性把所有的数据都给弄出来了,未做分页,假如数据达到了千万级,都查出来放入到List集合当中,有可能造成内存溢出。解决:更改申请对象的数量,比如说分页

  • 内存资源耗尽未释放:比如说使用线程或者使用数据库查询,在高并发情况下不断创建线程,或者不断的创建数据库连接,但是又没有去释放,久而久之就会溢出,比如说流创建比较多,但是没有去关闭。使用池化技术去优化代码

  • 本身资源不够:就是给堆分配的内存不够,因为在业务中可能会存在要创建大对象支撑业务正常运行,可以通过【jmap -heap PID :查看堆信息】。

  • 内存泄露导致内存不够,最终OOM。

死锁问题的定位

通过arthas方式定位:

通过arthas的thread命令,使用【thread -b】命令输出线程的统计信息,BLOCKED表示目前阻塞的线程数,命令执行后会直接输出造成死锁的线程ID和具体的代码位置以及当前线程一共阻塞的线程数量。

通过命令方式定位:

1、使用【jps -l】命令列出所有进程;

2、使用【jstack 进程id | grep ‘deadlock’ -A 100】命令,通过jstack命令和死锁关键字打印出这个进程出现死锁的堆栈信息。里面的信息会打印出代码的具体位置,是哪些线程造成死锁。

3、根据打印出来的堆栈信息,找到代码具体位置,然后根据业务去解决。

频繁Full GC问题

1、频繁FullGC会导致哪些问题

  • 系统卡顿:Full GC需要对整个堆进行扫描和处理,这个过程会导致应用程序的执行暂停。在这段时间内,应用程序无法响应用户请求,可能造成用户体验的下降或业务中断。

  • 长时间延迟:Full GC的执行时间较长,特别是当堆内存较大时。如果Full GC发生的频率较高或执行时间过长,可能会导致系统的响应时间变慢,影响系统的性能和吞吐量。

  • 内存占用过高从而影响其他服务正常运行:Full GC的执行通常需要消耗大量的CPU和内存资源。如果Full GC发生频繁且占用大量资源,可能会导致系统的资源消耗过高,从而影响其他应用程序或服务的正常运行。

  • 系统不稳定:Full GC执行期间,应用程序可能处于一个不可预测的状态,因为可能会触发一些不符合预期的行为。这可能导致应用程序的异常行为、内存泄漏等问题。

2、如何排查

详细的我写在内存泄露那块的排查了。

1、首先找到对应的服务,使用jps找到线程PID;

2、使用【jstat -gcutil PID 1000 10 】查看GC情况,FGC指的是Full GC数量

timestamp     S0     S1     E       O     M     CCS    YGC     YGCT    FGC    FGCT     GCTtimestamp:是距离JVM启动的时间
S0、S1、E:分别是新生代的两个Survivor和Eden
O:是老年代区域
M:是Metaspace,元空间
CCS:使用压缩比例
YUC、YGCT:分别是新生代GC的次数和时间
FGC、FGCT:分别是老年代GC的次数和时间
GCT:GC的总时间

3、使用jstat -gccause查看额外输出上次GC的原因

4、使用jmap -dump:format=b,file=heapdump 线程ID;导出dump文件

5、使用MAT或者JProfile工具进行分析

3、导致频繁FullGC的原因

  • 大对象,系统一次性加载了过多数据到内存:导致大对象直接进入到老年代;

  • 内存泄露,频繁创建了大量对象,但是无法被回收,先引发Full GC,最后导致OOM。

  • 程序频繁生成一些长声明周期的对象,当这些对象的平均年龄超过分代年龄时就会进入到老年代,最后老年代空间不够导致Full GC。

  • 程序BUG。

  • 代码里面显式调用了System.gc()。

  • JVM参数设置问题,包括总内存大小、新生代、老年代的大小、Eden区和幸存者S区的大小、元空间大小和垃圾回收算法等。

内存泄露问题的排查

不解决内存泄露会造成的影响:

  • 现象一:进程可用内存会变少导致结果就是OOM,发生了这个问题后可能就会想到堆内存不够大,于是就将-Xmx参数调大,然后重启应用,但是过了一段时间后,OOM还是出现了。这个时候堆内存参数无法再调大,就只能每隔一段时间重启一下应用。

  • 现象二:请求响应时间变长,这是因为频繁发生FullGC会暂停其他所有线程【Stop the world】造成的。

如何排查?

1、使用【jps -l】命令定位到进程号,因为线上如果有应用出现OOM,那么这个应用的进程号用jps肯定能找到。

2、使用【jstat -gcutil -t -h8 进程ID 1000】每隔1000ms打印一次该进程内存内GC活动情况,每8行输出一个行头信息。

root@8d36124607a0:/# jstat -gcutil -t -h8  进程ID   1000timestamp     S0     S1     E       O      M     CCS    YGC     YGCT    FGC    FGCT     GCT29.1       32.81   0.00  23.48  85.92  92.84  89.60   14      0.419    0     0.000    0.41930.1       32.81   0.00  78.12  85.92  92.84  89.60   14      0.419    0     0.000    0.41931.1       0.00    0.00  22.70  91.74  92.80  89.60   15      0.443    1     0.233    0.676timestamp:是距离JVM启动的时间
S0、S1、E:分别是新生代的两个Survivor和Eden
O:是老年代区域
M:是Metaspace,元空间
CCS:使用压缩比例
YUC、YGCT:分别是新生代GC的次数和时间
FGC、FGCT:分别是老年代GC的次数和时间
GCT:GC的总时间

3、观察以上GC参数,可以发现老年代内存O的占用率根本没有下降,说明有的对象无法被回收,也有可能这些对象是长期有用的。

4、使用【jmap -dump:live,format=b,file=/log/dempFile/heap.bin 进程ID 】dump出内存快照到指定目录下,然后将这个heap.bin文件下载下来,然后使用MAT工具或者JProfile工具导入dump文件进行排查,找到【Leak Suspects】选项,工具会自动帮我们列出所有可能发生内存泄露的对象以及对象的个数,之后找到代码的对应位置根据业务进行修改即可。
在这里插入图片描述

造成内存泄露的情况(列举几种):

  • 资源未关闭或释放导致内存泄露:在创建了各种连接【比如:数据库链接、网络IO和IO连接】,使用后未调用close()进行显式关闭,GC不会自动回收这些连接,大量对象未进行关闭就会引起内存泄露。

  • 使用了ThreadLocal未进行remove()引发的内存泄露。

  • 在代码中使用了大量的静态集合类:比如将HashMap、LinkedList等容器声明为静态,使得它们的生命周期与程序一致,容器内的元素在程序结束前不能被释放从而造成内存泄露。长生命周期的对象持有短生命周期对象的引用,尽管短生命周期的对象不再使用,但是因为长生命周期对象持有它的引用而导致不能被回收。

  • 单例模式:单例对象在初始化后会以静态变量的方式在JVM的整个声明周期中存在,如果单例对象持有外部引用,那么这个外部对象将不能被GC回收导致内存泄露。

  • 定义变量的作用于大于其适用范围:当设置一个全局变量在使用完未将其设置为null,可能会造成内存泄漏。

磁盘空间不足,如何排查Linux中的大文件位置

1、使用du命令去排查(常用):du命令可以查看磁盘空间的使用情况,自然也可以用来查看磁盘上占用空间较多的文件和文件夹。

# 查看当前目录下最大的前几个文件
du -ahx . | sort -rh | head -5
#查看根目录下所有文件的大小
du -sh /*  

2、使用find命令排查

# 如果要找前10个大文件
find $home -type f -printf '%s %p\n' | sort -nr | head -10     

尾声

其实线上问题的排查,一般就是top、free、df三连,然后再根据现象去定位是什么问题。

  • top命令:是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。进程状态显示和控制,每5s中自动刷新一次(动态显示)。
  • df指令:查看磁盘的使用率。
  • free指令:可以显示当前系统未使用的和已使用的内存数目,还可以显示被内核使用的内存缓冲区。

JVM常用的几个命令:

jps:查看正在运行的Java进程id
jstat:查看JVM内存的统计信息
jstack:打印JVM线程快照
jmap:导出内存映像文件&内存使用情况
.....

以上就是我平时开发中遇到的一些比较棘手的问题排查经验,没有带图片,不喜勿喷,后续等Arthas用熟了以后,再写一篇排查经验分享(二)的文章。

相关文章:

【经验分享】日常开发中的故障排查经验分享(一)

目录 简介CPU飙高问题1、使用JVM命令排查CPU飙升100%问题2、使用Arthas的方式定位CPU飙升问题3、Java项目导致CPU飙升的原因有哪些?如何解决? OOM问题(内存溢出)1、如何定位OOM问题?2、OOM问题产生原因 死锁问题的定位…...

关于Unity使用图片字体示例

1.使用TexturePacker打包图集 下载地址 TexturePacker - Create Sprite Sheets for your game! 2.准备好数字图 3. 导入图片 4. 打包图集需要的设置 将重心点设置为左下方 点击回车 > 后点击回 >到精灵列表 选择导出的格式 导出后的内容 >导入unity 导入 >…...

开源大语言模型简记

文章目录 开源大模型LlamaChinese-LLaMA-AlpacaLlama2-ChineseLinlyYaYiChatGLMtransformersGPT-3(未完全开源)BERTT5QwenBELLEMossBaichuan其他...

python高级代码

目录 列表推导式和生成器表达式:使用简洁的语法来生成列表和生成器。 装饰器:用于修改函数行为的函数。 上下文管理器:用于管理资源的对象,可以使用with语句来自动管理资源的分配和释放。 多线程和多进程编程:使用…...

透彻掌握GIT基础使用

网址 https://learngitbranching.js.org/?localezh_CN 清屏 clear重新开始reset...

二、类与对象(三)

17 初始化列表 17.1 初始化列表的引入 之前我们给成员进行初始化时,采用的是下面的这种方式: class Date { public:Date(int year, int month, int day)//构造函数{_year year;_month month;_day day;} private:int _year;int _month;int _day; };…...

CentOS 7 Tomcat服务的安装

前提 安装java https://blog.csdn.net/qq_36940806/article/details/134945175?spm1001.2014.3001.5501 1. 下载 wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.84/bin/apache-tomcat-9.0.84.tar.gzps: 可选择自己需要的版本下载安装https://mir…...

文件夹共享功能的配置 以及Windows server2012防火墙的配置

目录 一. 配置文件夹共享功能 1.1 为什么需要配置文件夹共享功能 1.2 配置文件夹共享 1.3 访问共享文件夹 1.4 配置取消 用户名和密码认证 二. windows server 2012防火墙配置 思维导图 一. 配置文件夹共享功能 1.1 为什么需要配置文件夹共享功能 我们在工作和生活中经…...

前端使用高德api的AMap.Autocomplete无效,使用AMap.Autocomplete报错

今天需要一个坐标拾取器,需要一个输入框输入模糊地址能筛选的功能 查看官方文档,有一个api可以直接满足我们的需求 AMap.Autocomplete 上代码 AMapLoader.load({"key": "你的key", // 申请好的Web端开发者Key,首次调…...

反转链表、链表的中间结点、合并两个有序链表(leetcode 一题多解)

一、反转链表 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 思路一:翻转单链表指针方向 这里解释一下三个指针的作用: n1&#xff1…...

深度学习中的Dropout

1 Dropout概述 1.1 什么是Dropout 在2012年,Hinton在其论文《Improving neural networks by preventing co-adaptation of feature detectors》中提出Dropout。当一个复杂的前馈神经网络被训练在小的数据集时,容易造成过拟合。为了防止过拟合&#xff…...

MySQL 中的 ibdata1 文件过大如何处理?

ibdata1 是什么文件? ibdata1 是InnoDB的共有表空间,默认情况下会把表空间存放在一个名叫 ibdata1的文件中,日积月累会使该文件越来越大。 ibdata1 文件过大的解决办法 使用独享表空间,将表空间分别单独存放。MySQL开启独享表空…...

Weblogic反序列化远程命令执行(CVE-2019-2725)

漏洞描述: CVE-2019-2725是一个Oracle weblogic反序列化远程命令执行漏洞,这个漏洞依旧是根据weblogic的xmldecoder反序列化漏洞,通过针对Oracle官网历年来的补丁构造payload来绕过。 复现过程: 1.访问ip:port 2.可…...

鸿蒙组件数据传递:ui传递、@prop、@link

鸿蒙组件数据传递方式有很多种,下面详细罗列一下: 注意: 文章内名词解释: 正向:父变子也变 逆向:子变父也变 **第一种:直接传递 - 特点:1、任何数据类型都可以传递 2、不能响应式…...

ubuntu 开机自报IP地址(用于无屏幕小车-远程连接)

目录 1.环境安装2.代码3.打包成可执行文件4.开启开机自启 1.环境安装 sudo apt-get install espeak #先安装这个库 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyttsx32.90 #再安装pyttsx3 pyinstaller pip install -i https://pypi.tuna.tsinghua.edu.cn/si…...

Angular——:host 和::deep

在Angular中,:host和::ng-deep是用于在组件样式中选择和修改宿主元素和子组件的特殊选择器。 :host是一个CSS伪类选择器,用于选择当前组件的宿主元素。它常用于在组件样式中应用样式到组件外部的宿主元素上。例如: :host {background-color:…...

键盘字符(#键)显示错误

当屏幕上显示的键与键盘上按下的键不同时,尤其是 # 键。大多数情况下,此错误是由于 raspbian 和 NOOBS 软件的默认英国键盘配置所致。 解决方案: 要解决此问题,您需要将配置更改为您自己的键盘或语言的配置。这可以通过转到树莓派…...

geemap学习笔记037:分析地理空间数据--坐标格网和渔网

前言 坐标格网(Coordinate Grid)简称“坐标网”,是按一定纵横坐标间距,在地图上划分的格网,坐标网是任何地图上不可缺少的要素之一。下面将详细介绍一下坐标格网和渔网。 1 导入库并显示地图 import ee import geem…...

Bluetooth Mesh 入门学习干货,参考Nordic资料(更新中)

蓝牙网状网络(Bluetooth mesh)概念 概述 蓝牙Mesh Profile | Bluetooth Technology Website规范(Mesh v1.1 后改名Mesh ProtocolMesh Protocol | Bluetooth Technology WebsiteMesh Protocol)是由蓝牙技术联盟(Bluetooth SIG)开…...

磁盘管理 :逻辑卷、磁盘配额

一 LVM可操作的对象:①完成的磁盘 ②完整的分区 PV 物理卷 VG 卷组 LV 逻辑卷 二 LVM逻辑卷管理的命令 三 建立LVM逻辑卷管理 虚拟设置-->一致下一步就行-->确认 echo "- - -" > /sys/class/scsi_host/host0/scan;echo "- -…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 ​…...