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

目录

  • 简介
  • 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用熟了以后,再写一篇排查经验分享(二)的文章。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2661009.html

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

相关文章

【力扣】20.有效的括号

家人们,看这排序,一看就很简单,对吧?不对,我觉得还挺不是很容易的,哈哈哈。 题解: 在看题目的时候,我一开始的解题思路就挺复杂的。题目说了”左括号必须以正确的顺序闭合“&#x…

PyTorch深度学习实战(29)——神经风格迁移

PyTorch深度学习实战(29)——神经风格迁移 0. 前言1. 神经风格迁移原理1.1 模型介绍1.2 GramMatrix 的重要性 2. 神经风格迁移模型构建策略3. 使用 Keras 实现神经风格迁移小结系列链接 0. 前言 神经风格迁移 (Neural Style Transfer) 是一种基于深度学…

C语言中的联合体的由来和存储

一、联合体的由来 1.1. 数据类型的不足 C语言中,基本数据类型只有整型、字符型、浮点型等少数几种,无法满足复杂数据类型的需要。 1.2. 数组的限制 虽然数组可以存储多个同类型的数据,但是数组中的元素个数是固定的,无法动态地…

【51单片机系列】DS18B20温度传感器扩展实验之设计一个智能温控系统

本文是关于DS18B20温度传感器的一个扩展实验。 文章目录 一、相关元件介绍二、实验分析三、proteus原理图设计四、软件设计 本扩展实验实现的功能:利用DS18B20设计一个智能温度控制系统,具有温度上下限值设定。当温度高于上限值时,电机开启&a…

[react]脚手架create-react-app/vite与reac项目

[react]脚手架create-react-app/vite与reac项目 环境问题描述create-react-app 脚手架根据脚手架修改项目结构安装脚手架注入配置文件-config文件夹package.json文件变更删除 serviceWorker.js新增reportWebVitals.js文件更新index.js文件 脚手架creat-react-app 缺点 vite 脚手…

Java技术栈 —— Nginx的使用

Java技术栈 —— Nginx的使用 一、认识Nginx二、搭建Nginx环境2.1 在Ubuntu上安装Nginx 三、使用Nginx3.1 配置负载均衡(HTTP) 一、认识Nginx 企业需要运行多个相同的副本,并将负载分散在整个系统集群上,为了高性能的负载均衡,引入了Nginx代…

阿里云30个公共云地域、89个可用区、5个金融云和政务云地域

阿里云基础设施目前已面向全球四大洲,公共云地域开服运营30个公共云地域、89个可用区,此外还拥有5个金融云、政务云地域,并且致力于持续的新地域规划和建设,从而更好的满足用户多样化的业务和场景需求。伴随着基础设施的加速投入和…

[RoarCTF2019] TankGame

不多说,用dnspy反编译data文件夹中的Assembly-CSharp文件 使用分析器分析一下可疑的FlagText 发现其在WinGame中被调用,跟进WinGame函数 public static void WinGame(){if (!MapManager.winGame && (MapManager.nDestroyNum 4 || MapManager.n…

【C语言】数据结构——排序(一)

💗个人主页💗 ⭐个人专栏——数据结构学习⭐ 💫点击关注🤩一起学习C语言💯💫 目录 导读:数组打印与交换1. 插入排序1.1 直接插入排序1.1.1 基本思想1.1.2 实现代码1.1.3 图解 1.2 希尔排序1.2.1…

机器人中的数值优化之无约束优化

欢迎大家关注我的B站: 偷吃薯片的Zheng同学的个人空间-偷吃薯片的Zheng同学个人主页-哔哩哔哩视频 (bilibili.com) 本文ppt来自深蓝学院《机器人中的数值优化》

人工智能的新篇章:深入了解大型语言模型(LLM)的应用与前景

LLM(Large Language Model)技术是一种基于深度学习的自然语言处理技术,旨在训练能够处理和生成自然语言文本的大型模型。 LLM 技术的核心思想是使用深度神经网络,通过大规模的文本数据预训练模型,并利用这些预训练模型…

伪装目标检测的算术不确定性建模

Modeling Aleatoric Uncertainty for Camouflaged Object Detection 伪装目标检测的算术不确定性建模背景贡献实验方法Camouflaged Object Detection Network(伪装目标检测框架)Online Confidence Estimation Network(在线置信度估计网络&…

【Week-P3】CNN天气识别

文章目录 一、环境配置二、准备数据三、搭建网络结构四、开始训练五、查看训练结果六、总结6.1 不改变学习率的前提下,将训练epoch分别增加到60、70、80、90(1)epoch 50 的训练情况如下:(2)epoch 60 的训…

Redis哨兵sentinel

是什么? 哨兵巡查监控后台master主机是否故障,如果故障根据投票数自动将某一个slave库变为master,就行对外服务,称为无人值守运维 能干嘛? 主从监控:监控主从redis库是否正常工作 消息通知:…

C++面向对象(OOP)编程-C++11新特性详解

C11作为一个重要的版本,引入了很多新的特性,解决了C语言本身很多遗留的内存泄露问题,并且提供了很多比较灵活的用法。引入的auto,智能指针、线程机制都使得C语言的灵活性、安全性、并发性有了很大的提升。 本文会比较详细的介绍C1…

YOLOv5改进 | 2023注意力篇 | FocusedLinearAttention聚焦线性注意力

一、本文介绍 本文给大家带来的改进机制是FLAttention(聚焦线性注意力)是一种用于视觉Transformer模型的注意力机制(但是其也可以用在我们的YOLO系列当中从而提高检测精度),旨在提高效率和表现力。其解决了两个在传统线性注意力方法中存在的…

MySQL 数据库归档工具pt-archive 与归档数据的安全存储 与 为什么每次归档都少数...

开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题,有需求都可以加群群内,可以解决你的问题。加群请联系 liuaustin3 ,(共1780人左右 1 2 3 4 5&#xff0…

java球队信息管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java Web球队信息管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5…

开源预约挂号平台 - 从0到上线

文章目录 开源预约挂号平台 - 从0到上线演示地址源码地址可以学到的技术前端技术后端技术部署上线开发工具其他技术业务功能 项目讲解前端创建项目 - 安装PNPM - 使用VSCODE - 安装插件首页顶部与底部 - 封装组建 - 使用scss左右布局中间内容部分路由 - vue-routerBANNER- 走马…

HCIA-Datacom题库(自己整理分类的)——OSPF协议判断

1.路由表中某条路由信息的Proto为OSPF则此路由的优先级一定为10。√ 2.如果网络管理员没有配置骨干区域,则路由器会自动创建骨干区域? 路由表中某条路由信息的Proto为OSPF,则此路由的优先级一定为10。 当两台OSPF路由器形成2-WAY邻居关系时&#xff0…