引言
在Java应用开发中,我们可能会遇到CPU占用过高和线程死锁的问题。本文将介绍如何使用Arthas工具快速定位这些问题。
准备工作
首先,我们创建一个简单的Java应用,模拟CPU过高和线程死锁的情况。在这个示例中,我们将编写一个名为CpuController的类,包含两个方法:loop()和deadlock()。
package your.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
@RestController
@Slf4j
public class CpuController {
private Object lock1 = new Object();
private Object lock2 = new Object();
@GetMapping("loop")
public String loop() {
log.warn("loop start");
while (true) {}
}
@GetMapping("deadlock")
public String deadlock() {
log.warn("deadlock start");
new Thread(()->{
synchronized (lock1) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {}
synchronized (lock2) {
log.info("thread1 over");
}
}
}).start();
new Thread(()->{
synchronized (lock2) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {}
synchronized (lock1) {
log.info("thread2 over");
}
}
}).start();
return "ok";
}
}
Arthas排查CPU过高过程
步骤一:通过thread
命令查看线程情况
thread
可以看到ID为17的线程CPU占用过高。
步骤二:通过thread 线程id
命令查看线程状态
thread 17
可以看出CpuController的20行代码,结合代码看出这里是一个死循环
Arthas排查线程死锁过程
步骤一:通过thread -b
命令查看线程死锁情况
thread -b
可以看出死锁已经产生了,结合代码可以看出死锁来源于CpuController的32行
步骤二:通过thread 线程id
命令查看线程状态
thread <Thread-7的ID>
thread <Thread-8的ID>
可以看出 Thread-7 和 Thread-8 都在等待对方的资源,造成死锁。
总结
通过以上步骤,我们使用Arthas成功定位了Java应用中的CPU过高和线程死锁问题。在实际项目中,遇到类似问题时,可以根据本文的排查步骤进行定位和解决。