CPU가 가장 많이 소모되는 자바 라인?

5733 단어 JVM
우리가 프로그램을 실행할 때 만약에 CPU가 대량으로 소모된다면 아마도 우리의 자바 프로그램에 문제가 생겼을 것이다. 대량의 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의 16진법 계산
printf "%x"5840
ethan@ubuntu:~$ printf "%x
" 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 상태임을 나타냅니다.

좋은 웹페이지 즐겨찾기