最消耗CPU的java线程?

当我们运行程序的时候,如果导致CPU大量被消耗,可能是我们的Java程序出现了问题,就需要定位到可能消耗大量CPU的线程,如何去做呢?

例如运行下面的程序


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class BusyThread {
    public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            br.readLine();
            createBusyThread();
            br.readLine();
            Object o = new Object();
            createLockThread(o);
            createDeadLoc();
            
    }

    public static void createBusyThread() {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true)
                    ;
            }
        }, "busyThreadName");
        t.start();
    }

    public static void createLockThread(final Object lock) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(lock) {
                    try {
                        lock.wait();
                    }catch(InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        },"lockThreadName");
        t.start();
    }
    public static void createDeadLoc() {
        Object a = new Object();
        Object b = new Object();
        
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (a) {
                    try {
                        Thread.sleep(3000);
                        synchronized (b) {
                            
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        },"t1");
        
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (b) {
                    try {
                        Thread.sleep(3000);
                        synchronized (a) {
                            
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        },"t2");
        t1.start();
        t2.start();
    }
}

1. 获取运行程序的进程id

jps -l
或者
ps -ef | grep BusyThread(运行程序类名)

ethan@ubuntu:~$ ps -ef | grep BusyThread
ethan      4688   1928  0 01:28 ?        00:00:14 /opt/sublime_text/sublime_text BusyThread.java
ethan      5728   5648  0 02:09 pts/4    00:00:00 java BusyThread
ethan      5789   5745  0 02:10 pts/6    00:00:00 grep --color=auto BusyThread

得到应用程序进程 id 为 5728

2. 获取对应进程下最消耗CPU 的线程 id

top -Hp 5728

top - 02:14:44 up  2:39,  1 user,  load average: 0.00, 0.12, 0.36
Threads:  14 total,   1 running,  13 sleeping,   0 stopped,   0 zombie
%Cpu(s): 99.3 us,  0.7 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  6057032 total,  3926028 free,  1285200 used,   845804 buff/cache
KiB Swap:  4191228 total,  4191228 free,        0 used.  4408076 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                   
  5840 ethan     20   0 3419616  27176  15840 R 94.7  0.4   0:03.97 java                                                      
  5737 ethan     20   0 3419616  27176  15840 S  0.3  0.4   0:00.34 java                                                      
  5728 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java                                                      
  5729 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.06 java                                                      
  5730 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.01 java                                                      
  5731 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java                                                      
  5732 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java                                                      
  5733 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java                                                      
  5734 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java                                                      
  5735 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java                                                      
  5736 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java                                                      
  5841 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java                                                      
  5842 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java                                                      
  5843 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java 

得到最消耗CPU的 线程 id 为 5840

3. 计算对应线程 id 的 十六进制

printf "%x\n" 5840

ethan@ubuntu:~$ printf "%x\n" 5840
16d0

4. 分析对应线程的堆栈信息

jstack 5728 | grep 16d0

ethan@ubuntu:~$ jstack 5728 | grep 16d0
"busyThreadName" #8 prio=5 os_prio=0 tid=0x00007fa5f80cb000 nid=0x16d0 runnable [0x00007fa5e346c000]

表明当前最占据CPU 的线程名为: busyThreadName ,当前处于 Runnable 状态

你可能感兴趣的:(JVM)