JVM分析(OOM、死锁、死循环)(JProfiler、arthas、jdk调优工具(命令行))

JVM分析(OOM、死锁、死循环)(JProfiler、arthas、jdk调优工具(命令行))

本文声明:

以下内容均为 JDK 8 + springboot 2.6.13 + (windows 11 或 CentOS 7.9.2009 )进行
ssh连接工具:FinalShell
请配合测试代码进行分析

一、测试代码

OOM

jvm参数:

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./heap/heapdump.hprof -XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xms12M -Xmx12M -Xloggc:./log/gc-oomHeap.log

idea配置地方

在这里插入图片描述

需要自己创建heap文件夹和log文件夹

在这里插入图片描述

参数含义

-XX:+HeapDumpOnOutOfMemoryError
在JVM发生OutOfMemoryError(内存溢出)时自动生成堆转储文件

-XX:HeapDumpPath=./heap/heapdump.hprof
指定堆转储文件的保存路径和文件名(当前目录下的heap文件夹中)

-XX:+PrintGCDateStamps
在GC日志中打印具体的日期时间戳(而不仅仅是相对时间)

-XX:+PrintGCDetails
打印详细的垃圾回收信息,包括GC前后内存变化、耗时等详细信息

-Xms12M
设置JVM初始堆内存大小为12MB,方便发生OOM

-Xmx12M
设置JVM最大堆内存大小为12MB(与-Xms相同,表示固定堆大小),方便发生OOM

-Xloggc:./log/gc-oomHeap.log
指定GC日志的输出路径和文件名(当前目录下的log文件夹中)

代码:OOMTest(没有使用springboot,因为OOM报错也是分析dump文件,使用springboot和正常使用java命令行是一样的)
public class OOMTest {public static void main(String[] args) {List<OOMObject> list = new ArrayList<>();while (true){list.add(new OOMObject());}}@Datastatic class OOMObject {private byte[] bytes = new byte[1024];}
}

死锁

代码:DeadLockTest2(springboot:配合多个线程分析)(为什么有个2,后面改了点代码已经打成jar包发linux,懒得改了)
@Service
public class DeadLockTest2 {private static Object lockA = new Object();private static Object lockB = new Object();@PostConstructpublic void init() {new Thread(()->{synchronized (lockA){try {Thread.sleep(1000);synchronized (lockB){System.out.println("线程A 获取到 lockB");}} catch (InterruptedException e) {e.printStackTrace();}}},"线程A").start();new Thread(()->{synchronized (lockB){try {Thread.sleep(1000);synchronized (lockA){System.out.println("线程B 获取到 lockA");}} catch (InterruptedException e) {e.printStackTrace();}}},"线程B").start();}
}

死循环

代码:DeadCycleTest(springboot:配合多个线程分析)
@Service
public class DeadCycleTest {@PostConstructpublic void init(){// 模拟有个线程一直在跑死循环,让springboot跑完main线程(启动的main方法)new Thread(()->{while (true){new DeadCycle();}}, "dead-cycle").start();}static class DeadCycle{}
}

二、jdk自带调优工具(通过命令行执行(在bash、cmd下执行))(我只讲我觉得比较重要的)(不是很好用,但要了解)(只要有jdk环境都能用)(以下案例在linux中完成)

工具所在目录:JDK的bin目录下

在这里插入图片描述

我只挑我认为比较重要的讲:JPS、JStack、JMap(Jcmd也行,相当于各个工具的整合升级版,可以自行学习)

jps:查看java项目进程pid

jps -l

jstack:使用jstack可查看指定进程(pid)的堆栈信息,用以分析线程情况(解决死锁、死循环)
命令适用场景
jstack <pid>常规线程状态检查,输出到文件分析
jstack -l <pid>强烈推荐,用于检测死锁和获取更详细的锁信息
jstack -F <pid>应用无响应时,强制生成线程转储
jstack -m <pid>诊断 JVM 本地方法或 JNI 代码问题

线程状态:

线程状态 (Thread.State)含义产生原因(常见调用方法)对CPU的影响排查方向
RUNNABLE可运行状态。线程正在 JVM 中执行代码,或准备就绪等待操作系统分配CPU时间片。1. 正在执行计算逻辑。 2. 可运行的线程,等待OS调度。。如果长期处于此状态,很可能是计算密集型任务或陷入循环。CPU高的罪魁祸首。查看堆栈,定位正在执行的方法。
BLOCKED阻塞状态。线程等待获取一个监视器锁(monitor lock),以便进入一个 synchronized 同步块/方法。该锁正被其他线程持有。等待进入 synchronized 方法或代码块。。线程未被调度,不消耗CPU。性能瓶颈/锁竞争。查看堆栈,等待的是哪个锁,并找出持有该锁的线程。
WAITING无限期等待。线程等待另一个线程执行某个特定的操作,没有时间限制Object.wait() Thread.join() LockSupport.park()。线程未被调度,不消耗CPU。程序逻辑设计如此,或可能在等待一个永远不会发生的条件。查看堆栈明确等待条件。
TIMED_WAITING有限期等待。线程等待另一个线程执行操作,但只等待指定的时间Thread.sleep(long) Object.wait(long) Thread.join(long) LockSupport.parkNanos() LockSupport.parkUntil()。线程在指定时间到期前不被调度。通常是正常状态(如休眠、等待I/O超时)。如果大量线程在此状态,可能连接池满或下游服务响应慢。
NEW初始状态。线程已被创建,但尚未启动(start()方法还未被调用)。new Thread() 之后,start() 之前。通常为瞬态,很少在快照中捕获到。
TERMINATED终止状态。线程已经执行完毕,结束了生命周期。run() 方法正常结束或因异常退出。通常为瞬态,很少在快照中捕获到。
jmap:查看堆内存使用情况、生成dump文件(一般来说是项目OOM挂了之后导出了dump文件(通过JVM参数:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./heap/heapdump.hprof),用软件进行分析,因为在生产使用 jmap 会造成 STW ,所以一般不用命令行导出文件)
命令作用对应用影响
jmap -heap <pid>查看堆配置和使用概况
jmap -histo <pid>查看所有对象统计信息
jmap -histo:live <pid>查看存活对象统计信息大(触发Full GC)(不要在生产环境高峰期频繁执行,会造成应用暂停(STW),影响用户体验)
jmap -dump:format=b,file=xxx.hprof <pid>生成完整堆转储大(可能阻塞,文件大)
jmap -dump:live,format=b,file=xxx.hprof <pid>生成存活对象堆转储大(触发Full GC,文件较小)(不要在生产环境高峰期频繁执行,会造成应用暂停(STW),影响用户体验)

分析解决问题:

OOM:OOMTest(后面用 JProfiler 可视化工具分析,下文会讲,没必要用命令行分析(jhat可以分析,但jhat不够简单,功能也不够强大))

我们通过 JProfiler 可视化工具分析,不用命令行执行(我写的 JDK 参数,包含了出现OOM会自动导出dump文件,在生产环境也是把dump文件下载到 windows 环境(IOS也行)用可视化工具分析(还有其他的,比如 eclipse 的 MAT、Oracle 的 visualVM 和 jconsole))

死锁:DeadLockTest2

用linux项目跑起来后,打印文件进一个log文件进行分析,用 jsp 得到我们项目的进程 PID(26934)(Jps也是个java进程)

[root@iZf8z9l17126rhrd9o9x07Z test]# jps -l
12658 -- process information unavailable
26934 test-0.0.1-SNAPSHOT.jar
27036 sun.tools.jps.Jps
[root@iZf8z9l17126rhrd9o9x07Z test]# jstack -l 26934 > ./DeadLock.log

DeadLock.log 文件内容(关键内容,乱码不影响观看,是真实的日志):

"线程B" #17 prio=5 os_prio=0 tid=0x00007f9dccf35800 nid=0x69d8 waiting for monitor entry [0x00007f9db4d8f000]java.lang.Thread.State: BLOCKED (on object monitor)at com.example.test.service.DeadLockTest2.lambda$init$1(DeadLockTest2.java:32)- waiting to lock <0x00000000eea985f8> (a java.lang.Object)- locked <0x00000000eea98460> (a java.lang.Object)at com.example.test.service.DeadLockTest2$$Lambda$566/1702143276.run(Unknown Source)at java.lang.Thread.run(Thread.java:750)Locked ownable synchronizers:- None"线程A" #16 prio=5 os_prio=0 tid=0x00007f9dcceb1800 nid=0x69d7 waiting for monitor entry [0x00007f9db4e90000]java.lang.Thread.State: BLOCKED (on object monitor)at com.example.test.service.DeadLockTest2.lambda$init$0(DeadLockTest2.java:19)- waiting to lock <0x00000000eea98460> (a java.lang.Object)- locked <0x00000000eea985f8> (a java.lang.Object)at com.example.test.service.DeadLockTest2$$Lambda$565/33533830.run(Unknown Source)at java.lang.Thread.run(Thread.java:750)Locked ownable synchronizers:- NoneFound one Java-level deadlock:
=============================
"线程B":waiting to lock monitor 0x00007f9db00062c8 (object 0x00000000eea985f8, a java.lang.Object),which is held by "线程A"
"线程A":waiting to lock monitor 0x00007f9d80002178 (object 0x00000000eea98460, a java.lang.Object),which is held by "线程B"Java stack information for the threads listed above:
===================================================
"线���B":at com.example.test.service.DeadLockTest2.lambda$init$1(DeadLockTest2.java:32)- waiting to lock <0x00000000eea985f8> (a java.lang.Object)- locked <0x00000000eea98460> (a java.lang.Object)at com.example.test.service.DeadLockTest2$$Lambda$566/1702143276.run(Unknown Source)at java.lang.Thread.run(Thread.java:750)
"线程A":at com.example.test.service.DeadLockTest2.lambda$init$0(DeadLockTest2.java:19)- waiting to lock <0x00000000eea98460> (a java.lang.Object)- locked <0x00000000eea985f8> (a java.lang.Object)at com.example.test.service.DeadLockTest2$$Lambda$565/33533830.run(Unknown Source)at java.lang.Thread.run(Thread.java:750)Found 1 deadlock.

可以看见上面信息:线程B、线程A的状态都被阻塞了java.lang.Thread.State: BLOCKED,最后一行还是发现了一个死锁,从堆栈信息也可以看出是DeadLockTest2的19行和32行出问题了

在这里插入图片描述

死循环:DeadCycleTest
windows:

jprofiler 在线分析(这个后面说到jprofiler的时候说)

方法一:由于实际的业务一个死循环里面不可避免有对象的创建,而创建多了就会有gc,可以通过对象的创建消亡查看,并通过对象来定位

方法二:还可以通过cpu占用率和线程存活时间来鉴别,通过包>类>方法来定位

linux:
1、首先定位CPU占用进程较高的进程ID

使用top指令进行查看各个进程的资源占有情况,观察出CPU占有较高的进程ID

top

在这里插入图片描述

2、根据进程ID查找导致CPU飙升的线程信息( 26934 是 java 进程 PID )
ps H -eo pid,tid,%cpu | grep 26934
各参数含义
- `ps`:用于查看当前运行的进程状态。
- `H`:显示进程的线程层级(线程树)。`ps` 默认显示进程,但加上 `H` 后,它会显示每个进程的线程(如果该进程有多个线程的话),并以树状结构展示。
- `-eo pid, tid, %cpu`:- `pid`:显示进程的 PID(进程标识符)。- `tid`:显示线程的 TID(线程标识符),即线程的 ID。- `%cpu`:显示该进程或线程使用的 CPU 百分比。
-`| grep 26934`:通过 `grep` 过滤,查找包含 `26934` 的行,通常用于筛选出与特定进程或线程相关的信息。

在这里插入图片描述

3、查找该线程的堆栈信息

首先将线程ID转换成16进制

[root@iZf8z9l17126rhrd9o9x07Z test]# printf "%x\n" 27094
69d6

线程id(27094)转换成16进制,输出结果为69d6

接着使用jstack指令来获取进程 ID 为 26934 的 Java 程序的所有线程堆栈信息

[root@iZf8z9l17126rhrd9o9x07Z test]# jstack 26934 | grep -A 10 69d6 > DeadLoop.log生成进程ID为 26934 的所有线程堆栈信息,并且查找 69d6 后面的10行信息并打印
指令参数如下:
- `jstack 26934`:打印出Java程序中ID为 26934 的进程中所有线程的堆栈信息快照
- `|`:管道符,表示将 `jstack` 命令的输出传递给后续的命令
- `grep -A 10 69d6`:查找到 69d6 的后10行记录信息- `grep` 进行文本搜索- `-A 10` 显示后10行的信息- `69d6` 搜索要求是 69d6

通过观察最后显示的进程为 26934,线程为 69d6 的堆栈信息情况,我们可以定位到导致CPU飙升的代码所在位置。

4、通过输出文件找问题:

DeadLoop.log

"dead-cycle" #15 prio=5 os_prio=0 tid=0x00007f9dcceb0800 nid=0x69d6 runnable [0x00007f9db4f91000]java.lang.Thread.State: RUNNABLEat com.example.test.service.DeadCycleTest.lambda$init$0(DeadCycleTest.java:14)at com.example.test.service.DeadCycleTest$$Lambda$564/20853837.run(Unknown Source)at java.lang.Thread.run(Thread.java:750)"container-0" #14 prio=5 os_prio=0 tid=0x00007f9dcce6c000 nid=0x69d5 waiting on condition [0x00007f9db5092000]java.lang.Thread.State: TIMED_WAITING (sleeping)at java.lang.Thread.sleep(Native Method)at org.apache.catalina.core.StandardServer.await(StandardServer.java:566)at org.springframework.boot.web.embedded.tomcat.TomcatWebServer$1.run(TomcatWebServer.java:197)

找代码 DeadCycleTest 类下的 14 行,找到改掉就好了

在这里插入图片描述

三、JProfiler(该工具是可视化工具,所以以下操作在windows环境下进行,但OOM一般都是从生产环境下载dump文件,再在windows下使用工具进行分析,跟我讲解的步骤类似)

// Download JProfiler 下载
// 适用于JProfiler最新版本的注册码,谁还会想要使用破解版呢。

// v13
S-NEO_PENG#890808-g4tibemn0jen#37bb9

// v14
S-J14-NEO_PENG#890808-1jqjtz91lywcp9#23624

// v15
S-J15-NEO_PENG#890808-1a6eo5gvl1w9v#b6bab

OOM:OOMTest

OOMTest 跑起来并且报 OOM 退出后,我们得到了一个dump文件(hprof)

在这里插入图片描述

使用jprofiler打开

在这里插入图片描述

我们一般就找最大的对象byte[],右键选定对象:

在这里插入图片描述

找出他的引入对象:

在这里插入图片描述

挨个找,第一个不是我们自己写的,略过,找第二个

在这里插入图片描述

位置是 com.example.test.OOMTest 下的 main 方法,去代码里面找到,发现这个一直放到 list 里面去死循环,根据可达性算法,对象一直有被引用不能被gc,所以最后OOM了,修改此处代码再运行再分析

在这里插入图片描述

题外:java.lang.OutOfMemoryError: Java heap space这是堆溢出了,还有些情况也会OOM,比如元空间溢出了java.lang.OutOfMemoryError: Metaspace(概率很小近乎不可能,原因一般是类太多了,导致方法区满了,所以最好的办法是加内存)

下面是报错案例,可以自己去分析一下

JVM参数-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./heap/heapdump.hprof -XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xms64M -Xmx64M -XX:MetaspaceSize=10M -XX:MaxMetaspaceSize=12M -Xloggc:./log/gc-oomHeap.log

-XX:MetaspaceSize=10M 元空间初始化容量 10M(一般不要用)

-XX:MaxMetaspaceSize=12M 元空间最大容量限制 12M(一般不要用)

其他的参数前面有

public class MetaSpaceOOMTest extends ClassLoader{public static void main(String[] args) {int i = 0;MetaSpaceOOMTest metaSpaceOOMTest = new MetaSpaceOOMTest();while (true){// ClassWriter对象,用于创建类的二进制字节码ClassWriter classWriter = new ClassWriter(0);// 创建类的字节码,指明类的版本、修饰符、类名、父类、接口classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "Class" + i, null, "java/lang/Object", null);// 返回类的字节码byte[] code = classWriter.toByteArray();// 类的加载metaSpaceOOMTest.defineClass("Class" + i, code, 0, code.length);i++;}}
}

死锁:DeadLockTest2

方法一:Attach分析(项目已经跑起来了,再进行监测)

打开我们跑的项目(启动中心>快速Attach>选择我们跑起来的项目):

在这里插入图片描述

选第二个Sampling

在这里插入图片描述

在 线程>线程历史 可以看见 线程A 和 线程B 被阻塞了

在这里插入图片描述

我们右键选择线程的热点树

在这里插入图片描述

就可以看见哪里出问题了

在这里插入图片描述

方法二:在Idea使用JProfiler插件,使用插件启动后,可以更直观看见哪里出现了死锁

再idea下载jprofiler插件

在这里插入图片描述

在右上角选择jprofiler运行项目,点击后会自动打开JProfiler:

在这里插入图片描述

查看当前锁状态图,把鼠标放到线上就可以看见哪出问题了

在这里插入图片描述

死循环:DeadCycleTest

jprofiler在线分析(方法一:由于实际的业务一个死循环里面不可避免有对象的创建,而创建多了就会有gc,可以通过对象的创建消亡查看,并通过对象来定位,方法二:还可以通过cpu占用率和线程存活时间来鉴别,通过包>类>方法来定位)

方法一:通过对象的大批量创建和销毁定位问题

先把对象转储再gc,再转储,对比两次对象的情况

在这里插入图片描述

可以看见,这个对象被大量的创建和销毁,通过全类目就可以定位到问题所在了

在这里插入图片描述

方法二:通过cpu占用率和线程存活时间来定位问题

在线程里面看见dead-cycle这个线程一直在跑

在这里插入图片描述

查看热点树

在这里插入图片描述

就可以定位问题所在了

在这里插入图片描述

四、arthas(用于生产环境定位问题所在,所以以下都是在linux环境下进行)

Arthas 是 Alibaba 开源的 Java 诊断工具,深受开发者喜爱。arthas官网

Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。

1、安装Arthas

[root@iZf8z9l17126rhrd9o9x07Z test]# wget https://arthas.aliyun.com/arthas-boot.jar;
--2025-09-03 13:45:44--  https://arthas.aliyun.com/arthas-boot.jar
正在解析主机 arthas.aliyun.com (arthas.aliyun.com)... 203.119.144.202
正在连接 arthas.aliyun.com (arthas.aliyun.com)|203.119.144.202|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:144630 (141K) [application/java-archive]
正在保存至: “arthas-boot.jar”100%[====================================================================================================================================================>] 144,630     --.-K/s 用时 0.1s    2025-09-03 13:45:45 (989 KB/s) - 已保存 “arthas-boot.jar” [144630/144630])

2、启动Arthas

选择第二个,第二个是我们启动的项目

[root@iZf8z9l17126rhrd9o9x07Z test]# java -jar arthas-boot.jar 
[INFO] JAVA_HOME: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.412.b08-1.el7_9.x86_64/jre
[INFO] arthas-boot version: 4.0.5
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 12658 -- process information unavailable[2]: 26934 test-0.0.1-SNAPSHOT.jar
2

出现下面的 banner 就说准备就绪了

在这里插入图片描述

OOM:OOMTest(还是使用下载dump文件,在JProfiler中排查的方式进行)

死锁:DeadLockTest2

1、查看线程使用情况

使用thread(太多了,截取了一点)查看线程使用情况,使用thread -b(完整的)找出当前阻塞其他线程的线程

[arthas@26934]$ thread
Threads Total: 37, NEW: 0, RUNNABLE: 11, BLOCKED: 2, WAITING: 14, TIMED_WAITING: 5, TERMINATED: 0, Internal threads: 5                                                                        
ID      NAME                                           GROUP                   PRIORITY        STATE           %CPU            DELTA_TIME      TIME           INTERRUPTED     DAEMON          
15      dead-cycle                                     main                    5               RUNNABLE        99.63           0.199           216:48.203     false           false           
-1      C1 CompilerThread1                             -                       -1              -               0.37            0.000           0:2.602        false           true            
44      arthas-command-execute                         system                  5               RUNNABLE        0.15            0.000           0:0.005        false           true            
18      lettuce-timer-3-1                              main                    5               TIMED_WAITING   0.09            0.000           0:6.148        false           true            
-1      VM Periodic Task Thread                        -                       -1              -               0.07            0.000           0:9.875        false           true            
16      线程A                                            main                    5               BLOCKED         0.01            0.000           0:0.357        false           false           
-1      C2 CompilerThread0                             -                       -1              -               0.01            0.000           0:8.571        false           true            
17      线程B                                            main                    5               BLOCKED         0.01            0.000           0:0.328        false           false           [arthas@26934]$ thread -b
"线程B" Id=17 BLOCKED on java.lang.Object@2d11bb3d owned by "线程A" Id=16at com.example.test.service.DeadLockTest2.lambda$init$1(DeadLockTest2.java:32)-  blocked on java.lang.Object@2d11bb3d-  locked java.lang.Object@1b294e9c <---- but blocks 1 other threads!at com.example.test.service.DeadLockTest2$$Lambda$566/1702143276.run(Unknown Source)at java.lang.Thread.run(Thread.java:750)
2、我们逐句分析thread -b的内容
"线程B" Id=17 BLOCKED on java.lang.Object@2d11bb3d owned by "线程A" Id=16
  • "线程B""线程A":线程的名称。
  • Id=17Id=16:JVM 分配给线程的唯一ID。
  • BLOCKED:这是线程的状态BLOCKED 状态意味着“线程B”正在积极地等待获取一个监视器锁(monitor lock,即 synchronized 锁),但这个锁目前被其他线程持有。它无法继续执行,直到获得这个锁。
  • on java.lang.Object@2d11bb3d:这是“线程B”想要获取的锁对象的地址@ 后面的十六进制数是对象在内存中的哈希码)。
  • owned by "线程A" Id=16:明确指出这个锁(@2d11bb3d)当前正被“线程A”持有

第一行总结: “线程B” 被阻塞了,因为它想拿到一个锁,而这个锁正在被 “线程A” 占着。


2. at com.example.test.service.DeadLockTest2.lambda$init$1(DeadLockTest2.java:32)
  • 这指出了“线程B”被阻塞时正在执行的代码位置
  • 它停在 DeadLockTest2 类的 lambda$init$1 方法中(这通常是一个Lambda表达式),具体是在这个文件的第32行
  • 第32行很可能是一个 synchronized(lock) 代码块,或者是一个调用了 synchronized 方法的地方。

3. - blocked on java.lang.Object@2d11bb3d
  • 这再次确认了第一行的信息:“线程B”正在等待锁对象 @2d11bb3d

4. - locked java.lang.Object@1b294e9c <---- but blocks 1 other threads!
  • 这是最关键的一行,它揭示了死锁的核心。
  • locked java.lang.Object@1b294e9c:虽然“线程B”在等待锁 A(@2d11bb3d),但它自己已经持有了另一个锁 B(@1b294e9c)
  • <---- but blocks 1 other threads!JVM 给你的一个重要提示! 它告诉你,“线程B”持有的这个锁 B(@1b294e9c) 正在阻塞着另外 1 个线程(很可能就是“线程A”),导致那个线程无法执行。

5. at com.example.test.service.DeadLockTest2$$Lambda$566/1702143276.run(Unknown Source) at java.lang.Thread.run(Thread.java:750)
  • 这是线程的调用栈,显示它是从一个Lambda表达式开始,最终通过 Thread.run 运行的。

死循环:DeadCycleTest

1、查看所有线程的CPU耗时排名(显示繁忙的线程)

thread -i 1000:统计最近 1000ms 内的线程 CPU 时间。可以看见 dead-cycle 线程 cpu占用率 98.99(太多了,截取了一点)

[arthas@26934]$ thread -i 1000
Threads Total: 37, NEW: 0, RUNNABLE: 11, BLOCKED: 2, WAITING: 14, TIMED_WAITING: 5, TERMINATED: 0, Internal threads: 5                                                                        
ID      NAME                                           GROUP                   PRIORITY        STATE           %CPU            DELTA_TIME      TIME           INTERRUPTED     DAEMON          
15      dead-cycle                                     main                    5               RUNNABLE        98.99           0.990           231:6.170      false           false           
-1      VM Periodic Task Thread                        -                       -1              -               0.05            0.000           0:10.547       false           true            
-1      C1 CompilerThread1                             -                       -1              -               0.04            0.000           0:2.680        false           true            
18      lettuce-timer-3-1                              main                    5               TIMED_WAITING   0.03            0.000           0:6.468        false           true            
44      arthas-command-execute                         system                  5               RUNNABLE        0.02            0.000           0:0.028        false           true   
2、定位问题位置
方法一、通过上诉的线程信息,查看线程id为15的完整调用堆栈

thread 15可以看见问题所在代码的 DeadCycleTest 类的 14 行

[arthas@26934]$ thread 15
"dead-cycle" Id=15 RUNNABLEat com.example.test.service.DeadCycleTest.lambda$init$0(DeadCycleTest.java:14)at com.example.test.service.DeadCycleTest$$Lambda$564/20853837.run(Unknown Source)at java.lang.Thread.run(Thread.java:750)
方法二、列出 1000ms 内最忙的 5 个线程栈

thread -n 5 -i 1000:列出 1000ms 内最忙的 5 个线程栈。(我这展示两条进行对比就行了),可以看见 dead-cycle 的 cpu 占用率99.86%,也可以看见问题所在代码的 DeadCycleTest 类的 14 行

[arthas@26934]$ thread -n 5
"dead-cycle" Id=15 cpuUsage=99.86% deltaTime=200ms time=13489381ms RUNNABLEat com.example.test.service.DeadCycleTest.lambda$init$0(DeadCycleTest.java:14)at com.example.test.service.DeadCycleTest$$Lambda$564/20853837.run(Unknown Source)at java.lang.Thread.run(Thread.java:750)"lettuce-timer-3-1" Id=18 cpuUsage=0.02% deltaTime=0ms time=6331ms TIMED_WAITINGat java.lang.Thread.sleep(Native Method)at io.netty.util.HashedWheelTimer$Worker.waitForNextTick(HashedWheelTimer.java:600)at io.netty.util.HashedWheelTimer$Worker.run(HashedWheelTimer.java:496)at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)at java.lang.Thread.run(Thread.java:750)

参考文档:

JAVA项目线上CPU飙升的问题排查CPU飙升引发的问题: 系统相应迟钝:CPU占用过高时,系统处理请求的速度会变慢

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习中的数据增强实战:基于PyTorch的图像分类任务优化

在深度学习的图像分类任务中&#xff0c;我们常常面临一个棘手的问题&#xff1a;训练数据不足。无论是小样本场景还是模型需要更高泛化能力的场景&#xff0c;单纯依靠原始数据训练的模型很容易陷入过拟合&#xff0c;导致在新数据上的表现不佳。这时候&#xff0c;数据增强&a…

IEEE 802.11 MAC架构解析:DCF与HCF如何塑造现代Wi-Fi网络?

IEEE 802.11 MAC架构解析:DCF与HCF如何塑造现代Wi-Fi网络? 你是否曾好奇,当多个设备同时连接到同一个Wi-Fi网络时,它们是如何避免数据冲突并高效共享无线信道的?这背后的核心秘密就隐藏在IEEE 802.11标准的MAC(媒体访问控制)子层架构中。今天,我们将深入解析这一架构的…

深入掌握sed:Linux文本处理的流式编辑器利器

一、前言&#xff1a;sed是什么&#xff1f; 二、sed的工作原理 数据处理流程&#xff1a; 详细工作流程&#xff1a; 三、sed命令常见用法 基本语法&#xff1a; 常用选项&#xff1a; 常用操作命令&#xff1a; 四、实用示例演示 1. 输出符合条件的文本&#xff08;…

k8s三阶段项目

k8s部署discuz论坛和Tomcat商城 一、持久化存储—storageclassnfs 1.创建sa账户 [rootk8s-master scnfs]# cat nfs-provisioner-rbac.yaml # 1. ServiceAccount&#xff1a;供 NFS Provisioner 使用的服务账号 apiVersion: v1 kind: ServiceAccount metadata:name: nfs-prov…

Zynq开发实践(FPGA之流水线和冻结)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】谈到fpga相比较cpu的优势&#xff0c;很多时候我们都会谈到数据并发、边接收边处理、流水线这三个方面。所以&#xff0c;第三个优势&#xff0c;也…

接口保证幂等性你学废了吗?

接口幂等性定义&#xff1a;无论一次或多次调用某个接口&#xff0c;对资源产生的副作用都是一致的。 简单来说&#xff1a;用户由于各种原因&#xff08;网络超时、前端重复点击、消息重试等&#xff09;对同一个接口发了多次请求&#xff0c;系统只能处理一次&#xff0c;不能…

入行FPGA选择国企、私企还是外企?

不少人想要转行FPGA&#xff0c;但不知道该如何选择公司&#xff1f;下面就来为大家盘点一下FPGA大厂的薪资和工作情况&#xff0c;欢迎大家在评论区补充。一、老牌巨头在 FPGA设计 领域深耕许久&#xff0c;流程完善、技术扎实&#xff0c;公司各项制度都很完善&#xff0c;前…

考研总结,25考研京区上岸总结(踩坑和建议)

我的本科是一所普通的双非&#xff0c;其实&#xff0c;从我第一天入学时候&#xff0c;我就想走出去&#xff0c;开学给我带来的更多是失望&#xff08;感觉自己高考太差劲了&#xff09;&#xff0c;是不甘心&#xff08;自己一定可以去更好的地方&#xff09;。我在等一次机…

基于数据挖掘的当代不孕症医案证治规律研究

标题:基于数据挖掘的当代不孕症医案证治规律研究内容:1.摘要 背景&#xff1a;随着现代生活方式的改变&#xff0c;不孕症的发病率呈上升趋势&#xff0c;为探索有效的中医证治规律&#xff0c;数据挖掘技术为其提供了新的途径。目的&#xff1a;运用数据挖掘方法研究当代不孕症…

《sklearn机器学习》——调整估计器的超参数

GridSearchCV 详解&#xff1a;网格搜索与超参数优化 GridSearchCV 是 scikit-learn 中用于超参数调优的核心工具之一。它通过系统地遍历用户指定的参数组合&#xff0c;使用交叉验证评估每种组合的性能&#xff0c;最终选择并返回表现最优的参数配置。这种方法被称为网格搜索&…

一站式可视化运维:解锁时序数据库 TDengine 的正确打开方式

小T导读&#xff1a;运维数据库到底有多复杂&#xff1f;从系统部署到数据接入&#xff0c;从权限配置到监控告警&#xff0c;动辄涉及命令行、脚本和各种文档查找&#xff0c;一不留神就可能“翻车”。为了让 TDengine 用户轻松应对这些挑战&#xff0c;我们推出了《TDengine …

多线程同步安全机制

目录 以性能换安全 1.synchronized 同步 &#xff08;1&#xff09;不同的对象竞争同一个资源&#xff08;锁得住&#xff09; &#xff08;2&#xff09;不同的对象竞争不同的资源&#xff08;锁不住&#xff09; &#xff08;3&#xff09;单例模式加锁 synchronized …

多路复用 I/O 函数——`select`函数

好的&#xff0c;我们以 Linux 中经典的多路复用 I/O 函数——select 为例&#xff0c;进行一次完整、深入且包含全部代码的解析。 <摘要> select 是 Unix/Linux 系统中传统的多路复用 I/O 系统调用。它允许一个程序同时监视多个文件描述符&#xff08;通常是套接字&…

嵌入式碎片知识总结(二)

1.repo的一个问题&#xff1a;repo init -u ssh://shchengerrit.bouffalolab.com:29418/bouffalo/manifest/bouffalo_sdk -b master -m allchips-internal.xml /usr/bin/repo:681: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in…

java中二维数组笔记

课程链接:黑马程序员java零基础[上] 1.二维数组的内存分布 在 Java 中&#xff0c;二维数组并不是一整块连续的二维空间&#xff0c;而是数组的数组。具体而言,在声明一个二维数组&#xff1a;如int[][] arr new int[2][3];时&#xff0c;内存中会发生如下: 1.1 栈上的引用变…

系统架构设计师备考第13天——计算机语言-多媒体

一、多媒体基础概念媒体的分类 感觉媒体&#xff1a;人类感官直接接收的信息形式&#xff08;如声音、图像&#xff09;。表示媒体&#xff1a;信息的数字化表示&#xff08;如JPEG图像、MP3音频&#xff09;。显示媒体&#xff1a;输入/输出设备&#xff08;如键盘、显示器&am…

指针高级(1)

1.指针的运算2.指针运算有意义的操作和无意义的操作、#include <stdio.h> int main() {//前提条件&#xff1a;保证内存空间是连续的//数组int arr[] { 1,2,3,4,5,6,7,8,9,10 };//获取0索引的内存地址int* p1 &arr[0];//通过内存地址&#xff08;指针P&#xff09;…

【可信数据空间-Trusted Data Space综合设计方案】

可信数据空间-Trusted Data Space综合设计方案 一.简介与核心概念 1.什么是可信数据空间 2.核心特征 3.主要应用场景 二、 产品设计 1. 产品定位 2. 目标用户 3. 核心功能模块 a. 身份与访问管理 b. 数据目录与服务发现 c. 策略执行与合约管理 d. 数据连接与计算 e. 审计与溯源…

技术方案之Mysql部署架构

一、序言在后端系统中&#xff0c;MySQL 作为最常用的关系型数据库&#xff0c;其部署架构直接决定了业务的稳定性、可用性和扩展性。你是否遇到过这些问题&#xff1a;单机 MySQL 突然宕机导致业务中断几小时&#xff1f;高峰期数据库压力过大&#xff0c;查询延迟飙升影响用户…

js语言编写科技风格博客网站-详细源码

<!-- 科技风格博客网站完整源码 --> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <ti…