public class OOMTest {
public static void main(String[] args) {
List<OOMObject> list = new ArrayList<>();
while (true){
list.add(new OOMObject());
}
}
@Data
static class OOMObject {
private byte[] bytes = new byte[1024];
}
}
@Service
public class DeadLockTest2 {
private static Object lockA = new Object();
private static Object lockB = new Object();
@PostConstruct
public 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:配合多个线程分析)
java复制代码
@Service
public class DeadCycleTest {
@PostConstruct
public void init(){
// 模拟有个线程一直在跑死循环,让springboot跑完main线程(启动的main方法)
new Thread(()->{
while (true){
new DeadCycle();
}
}, "dead-cycle").start();
}
static class DeadCycle{
}
}
[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 文件内容(关键内容,乱码不影响观看,是真实的日志):
txt复制代码
"线程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:
- None
Found 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.
[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
[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 行
bash复制代码
[arthas@26934]$ thread 15
"dead-cycle" Id=15 RUNNABLE
at 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)
[arthas@26934]$ thread -n 5
"dead-cycle" Id=15 cpuUsage=99.86% deltaTime=200ms time=13489381ms RUNNABLE
at 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_WAITING
at 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)