JVM 线程诊断

1、CPU占用过高

# 1、定位哪个线程占用较高(查看pid)
top

# 2、进一步定位哪个线程引起的CPU占用过高
ps H -eo pid,tid,%cpu | grep <pid>

# 3、查看Java进程信息
jstack <pid>

但步骤2给出的tid结果是十进制的。需要进一步换算成16进制,即可定位到线程:

2、程序死锁(执行很久都没有结果)

# 同第一种情况,查看Java进程信息
jstack <pid>

可以在jstack输出的最后找到死锁信息:

线程诊断-死锁

死锁代码范例:

public class DeadlockExample {
    // 创建两个对象作为锁资源
    private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();

    public static void main(String[] args) {
        // 线程1
        Thread thread1 = new Thread(() -> {
            synchronized (lock1) {
                System.out.println("Thread 1: 持有 lock1,尝试获取 lock2");
                try {
                    Thread.sleep(1000); // 模拟一些处理时间
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock2) {
                    System.out.println("Thread 1: 同时持有 lock1 和 lock2");
                }
            }
        });

        // 线程2
        Thread thread2 = new Thread(() -> {
            synchronized (lock2) {
                System.out.println("Thread 2: 持有 lock2,尝试获取 lock1");
                try {
                    Thread.sleep(1000); // 模拟一些处理时间
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock1) {
                    System.out.println("Thread 2: 同时持有 lock2 和 lock1");
                }
            }
        });

        // 启动两个线程
        thread1.start();
        thread2.start();
    }
}

3、可以通过以下几种方法找到 Java 进程的 PID

方法 1:使用 JDK 提供的 jps 命令

jps -l

运行结果:
C:\Users\Huan_>jps -l
17008 D:\apache-jmeter-5.6.3\bin\ApacheJMeter.jar
2560 org.jetbrains.idea.maven.server.RemoteMavenServer36
22196
34468 com.hmdp.HmDianPingApplication
11992 org.jetbrains.jps.cmdline.Launcher
50696 com.hmdp.HmDianPingApplication
54024 jdk.jcmd/sun.tools.jps.Jps
17836

方法 2:在Linux系统下,使用 ps 命令

ps aux | grep java

运行结果:
user     12345  0.0  2.1 1234567 89012 ?  Sl   Apr27   0:10 java -jar myapp.jar
user     67890  0.1  3.4 2345678 91011 ?  Sl   Apr27   0:20 java -Dserver.port=8080 ...

 

This article was updated on