JVM-Cpu飙升排查及解决

https://blog.csdn.net/m0_37542440/article/details/123679011

1. 问题情况

在服务器上执行某个任务时,系统突然运行缓慢,top 发现cpu飙升,一度接近100%,最终导致服务假死。

2. 问题排查

  1. 执行 "top" 命令:查看所有进程占系统cpu的排序,极大可能排第一的就是自己的java进程,pid就是进程号。

  2. 执行 "top -Hp 进程号" 命令:查看java进程下的所有线程占cpu情况。

  3. 执行 "printf "%x\n" 10" 命令:后续查看线程堆栈信息展示的都是十六进制,为了找到咱们的线程堆栈信息,需要把线程号转为16进制。例如,printf "%x\n 10-》打印:a,那么在jstack中线程号就是0xa。

  4. 执行 "jstack 进程号 | grep 线程id" 命令:查找某进程下-》线程id(jstack堆栈信息中的nid)=0xa的线程状态。如果""VM Thread" os_prio=0 tid=0x00007f871806e000 nid=0xa runnable",第一个双引号圈起来的就是线程名,如果是"VM Thread"这就是虚拟机GC回收线程了。

  5. 执行 "jstat -gcutil 进程号 统计间隔毫秒 统计次数(缺省代表一致统一)",查看某进程GC持续变化情况,如果发现返回中FGC很大且一直增大,确认Full GC 也可以使用"jmap -heap 进程ID",查看一下进程堆内是不是要溢出了,特别是老年代内从使用情况一般是到达阈值(具体看垃圾回收器和启动配置的阈值)就回晋城Full GC。

  6. 执行 "jmap -dump:format=b,file=filename 进程ID",导致某进程下内存heap输出到文件中,可以通过eclipse的mat工具查看内存中有哪些对象比较多。

6-1. jmap

jmap -dump:live,format=b,file=live_web_dump.hprof 22260

借鉴:JVM调优命令-jmap - 钰火 - 博客园

3. 原因分析

  1. 内存消耗过啊,导致Full GC次数过多

执行步骤1-5:

多个线程的CPU都超过了100%,通过jstack命令可以看到这些线程主要是垃圾回收线程-》上一节步骤2

通过jstat命令监控GC情况,可以看到Full GC次数非常多,并且次数在不断增加。--》上一节步骤5

确定是Full GC,接下来找到具体原因:

生成大量的对象,导致内存溢出-》执行步骤6,查看具体内存对象占用情况。

内存占用不高,但是Full GC次数还是比较多,此时可能是代码中手动调用 System.gc()导致GC次数过多,这可以通过添加 -XX:+DisableExplicitGC来禁用JVM对显示GC的响应。

2.代码中有大量消耗CPU的操作,导致CPU过高,系统运行缓慢;

执行步骤1-4:在步骤4jstack,可直接定位到代码行。例如某些复杂算法,甚至算法BUG,无限循环递归等等。

3.由于锁使用不当,导致死锁。

执行步骤1-4: 如果有死锁,会直接提示。关键字:deadlock.步骤四,会打印出业务死锁的位置。

造成死锁的原因:最典型的就是2个线程互相等待对方持有的锁。

4.随机出现大量线程访问接口缓慢。

代码某个位置有阻塞性的操作,导致该功能调用整体比较耗时,但出现是比较随机的;平时消耗的CPU不多,而且占用的内存也不高。

思路:

首先找到该接口,通过压测工具不断加大访问力度,大量线程将阻塞于该阻塞点。

5.某个线程由于某种原因而进入WAITING状态,此时该功能整体不可用,但是无法复现;

执行步骤1-4:jstack多查询几次,每次间隔30秒,对比一直停留在parking 导致的WAITING状态的线程。例如CountDownLatch倒计时器,使得相关线程等待->AQS(AbstractQueuedSynchronizer AQS框架源码剖析)->LockSupport.park()。

相关推荐
欣栀♡1 小时前
JVM 频繁 Full GC 先看日志括号里的 cause,jstat 的 FGC 在 JDK 8 上会骗人
java·jvm
czt_java2 小时前
JVM 核心基础|运行时数据区、类加载机制、GC 分代回收
jvm
Web极客码4 小时前
Python Ollama 本地 Agent 入门与订单查询实践
开发语言·jvm·python
y = xⁿ5 小时前
一文掌握JVM
jvm
顺风尿一寸13 小时前
从 FileOutputStream 到 int fd:一次 JNI 字段读写全链路源码剖析
linux·jvm
用户0942485680313 小时前
第36章:JVMTI、Java Agent与运行时扩展点
java·jvm
脚踏实地,坚持不懈!13 小时前
Linux 内存回收机制:水位线、kswapd 与 Direct Reclaim
linux·jvm·算法
wuminyu14 小时前
ZGC染色指针在虚拟线程stackChunkOop上的并发屏障全景分析
java·linux·c语言·jvm·c++
江湖有缘1 天前
Docker实战 | 使用Docker部署rmoments社交平台
jvm·docker·oracle
H.莓飛2 天前
【C++】内存管理
linux·开发语言·jvm·c++·visual studio