CPU高的排查

以前有朋友反饋說發的內容但願有個梯度,逐步加深,前面發了幾篇關於jvm源碼分析的文章,可能我以爲我已經把內容寫得淺顯易懂了,可是對於某些沒怎麼接觸的同窗來講仍是比較難理解,這個我之後慢慢改進吧,今天發篇輕鬆點的文章,可能你們在工做過程當中也會可能碰到相似的問題,或許有經驗的同窗看到這個題目就知道我要說什麼了,也有本身的定位方法。java

話很少說了,先來看代碼吧web

public class Test{jvm

        public static void main(String args[]){源碼分析

                for(int i=0;i<10;i++){spa

                        new Thread(){線程

                                public void run(){進程

                                        try{源碼

                                                Thread.sleep(100000);it

                                        }catch(Exception e){}io

                                }

                        }.start();

                }

                Thread t=new Thread(){

                        public void run(){

                                int i=0;

                                while(true){

                                        i=(i++)/100;

                                }

                        }

                };

                t.setName("Busiest Thread");

                t.start();

        }

}

這個例子裏新建立了11個線程,其中10個線程沒幹什麼事,主要是sleep,另外有一個線程在循環裏一直跑着,能夠想象這個線程是這個進程裏最耗cpu的線程了,那怎麼把這個線程給抓出來呢?

首先咱們能夠經過top -Hp <pid>來看這個進程裏全部線程的cpu消耗狀況,獲得相似下面的數據

$ top -Hp 18207

top - 19:11:43 up 573 days,  2:43,  2 users,  load average: 3.03, 3.03, 3.02

Tasks:  44 total,   1 running,  43 sleeping,   0 stopped,   0 zombie

Cpu(s): 18.8%us,  0.0%sy,  0.0%ni, 81.1%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st

Mem:  99191752k total, 98683576k used,   508176k free,   128248k buffers

Swap:  1999864k total,   191064k used,  1808800k free, 17413760k cached

 

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND

18250 admin     20   0 26.1g  28m  10m R 99.9  0.0   0:19.50 java Test

18207 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18208 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.09 java Test

18209 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18210 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18211 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18212 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18213 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18214 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18215 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18216 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18217 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18218 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18219 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18220 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18221 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18222 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18223 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18224 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18225 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18226 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

18227 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test

拿到這個結果以後,咱們能夠看到cpu最高的線程是pid爲18250的線程,佔了99.8%:

 PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND

18250 admin     20   0 26.1g  28m  10m R 99.9  0.0   0:19.50 java Test

接着咱們能夠經過jstack <pid>的輸出來看各個線程棧:

$ jstack 18207

2016-03-30 19:12:23

Full thread dump OpenJDK 64-Bit Server VM (25.66-b60 mixed mode):

 

"Attach Listener" #30 daemon prio=9 os_prio=0 tid=0x00007fb90be13000 nid=0x47d7 waiting on condition [0x0000000000000000]

   java.lang.Thread.State: RUNNABLE

 

"DestroyJavaVM" #29 prio=5 os_prio=0 tid=0x00007fb96245b800 nid=0x4720 waiting on condition [0x0000000000000000]

   java.lang.Thread.State: RUNNABLE

 

"Busiest Thread" #28 prio=5 os_prio=0 tid=0x00007fb91498d000 nid=0x474a runnable [0x00007fb9065fe000]

   java.lang.Thread.State: RUNNABLE

    at Test$2.run(Test.java:18)

 

"Thread-9" #27 prio=5 os_prio=0 tid=0x00007fb91498c800 nid=0x4749 waiting on condition [0x00007fb906bfe000]

   java.lang.Thread.State: TIMED_WAITING (sleeping)

    at java.lang.Thread.sleep(Native Method)

    at Test$1.run(Test.java:9)

 

"Thread-8" #26 prio=5 os_prio=0 tid=0x00007fb91498b800 nid=0x4748 waiting on condition [0x00007fb906ffe000]

   java.lang.Thread.State: TIMED_WAITING (sleeping)

    at java.lang.Thread.sleep(Native Method)

    at Test$1.run(Test.java:9)

 

"Thread-7" #25 prio=5 os_prio=0 tid=0x00007fb91498b000 nid=0x4747 waiting on condition [0x00007fb9073fe000]

   java.lang.Thread.State: TIMED_WAITING (sleeping)

    at java.lang.Thread.sleep(Native Method)

    at Test$1.run(Test.java:9)

 

"Thread-6" #24 prio=5 os_prio=0 tid=0x00007fb91498a000 nid=0x4746 waiting on condition [0x00007fb9077fe000]

   java.lang.Thread.State: TIMED_WAITING (sleeping)

    at java.lang.Thread.sleep(Native Method)

    at Test$1.run(Test.java:9)

...

上面的線程棧咱們注意到nid的值其實就是線程ID,它是十六進制的,咱們將消耗cpu最高的線程18250,轉成十六進制0X47A,而後從上面的線程棧裏找到nid=0X47A的線程,其棧爲:

"Busiest Thread" #28 prio=5 os_prio=0 tid=0x00007fb91498d000 nid=0x474a runnable [0x00007fb9065fe000]

   java.lang.Thread.State: RUNNABLE

    at Test$2.run(Test.java:18)

即將最耗cpu的線程找出來了,是Businest Thread

相關文章
相關標籤/搜索