文章目录
- 前言
- 一、CPU占用过大
- 二、程序运行很长时间没有结果
- 三、总结
前言
本篇讲的排查都是基于Linux环境的。
一、CPU占用过大
这个一般是出现了死循环导致的。
1、先用top命令查看占用CPU的进程ID
top

2、再用ps命令查看对应的线程
就看一查看到对应的线程id
ps H -eo pid,tid,%cpu |grep 1678

3、jstack查看具体线程
jstack可以查看进程内所有的线程信息
jstack pid


可以看到一个线程名为main的线程,类名也就是我们用户写的类名,不是JDK的类名。
注意,我们用ps命令查看的进程ID和线程ID都是10进制的。
而jstack显示的线程ID是16进制的,所以,要转换一下。

1679对应的是68F,这样,对应jstack的nid。

从而定位到具体的线程报错。在Demo1.java第三行。

从这里,我们也可以总结出,在平时开发中,我们创建线程,一定要给线程命名。方便排查问题。
4、案例源码
public class Demo1 {
public static void main(String[] args) {
while (true){}
}
}
二、程序运行很长时间没有结果
这个一般是出现线程死锁。
1、先用top或者ps定位程序的进程ID
我这里是案例演示,所以,用top查看Java进程ID,因为,我的机器上只运行了一个Java程序。

2、用jstack查看线程信息
jstack pid



此时,我们定位到具体Java代码位置,然后,去分析,为什么产生死锁,针对性优化即可。
3、案例源码
public class Demo2 {
static byte[] a = new byte[1];
static byte[] b = new byte[1];
public static void main(String[] args) throws InterruptedException {
Thread thread01 = new Thread(() -> {
synchronized (a) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (b) {
System.out.println("我获得了a和b!");
}
}
});
thread01.setName("Thread01");
thread01.start();
Thread.sleep(1000);
Thread thread02 = new Thread(() -> {
synchronized (b) {
synchronized (a) {
System.out.println("我获得了a和b!");
}
}
});
thread02.setName("thread02");
thread02.start();
}
}
三、总结
先用top或者ps命令,找到Java进程ID,然后,用jstack工具定位到具体线程。
Java的线程问题,最终还是用jstack工具去排查。
其实,查看Java进程,还可以用jps命令。
所以,建议jps+jstack来排查Java线程问题。














![[Unity Demo]从零开始制作空洞骑士Hollow Knight第十一集:制作法术系统的回血机制和火球机制](https://i-blog.csdnimg.cn/direct/ce838b2fd6874d5585773fcf219c1c00.png)




