Java線程詳細監控和其dump的分析使用—-分析Java性能瓶頸


這里對linux下、sun(oracle) JDK的線程資源占用問題的查找步驟做一個小結;
linux環境下,當發現java進程占用CPU資源很高,且又要想更進一步查出哪一個java線程占用了CPU資源時,按照以下步驟進行查找:
(一):通過【 top  -p 12377 -H】 查看java進程的有哪些線程的運行情況;
      和通過【jstack 12377 > stack.log】生成Java線程的dump詳細信息;
    1. 先用top命令找出占用資源厲害的java進程id,如圖:# top
    2. 如上圖所示,java的進程id為’52554′,接下來用top命令單獨對這個進程中的所有線程作監視:
  1. 1 top  -p 52554 -H

     

    #  top視圖里面里面可以通過快捷鍵依次b ,x高亮顯示top的列找出需要的線程,默認CPU排序,Shift+< ,Shift+>可以左右移動高亮排序的列;

    如圖:(這時就看出來哪個java線程CPU高,哪個線程內存用的多)

  2. 如上圖所示,linux下,所有的java內部線程,其實都對應了一個進程id,也就是說,linux上的sun jvm將java程序中的線程映射為了操作系統進程;我們看到,占用CPU資源最高的那個進程id是’15417′,這個進程id對應java線程信息中的’nid’(‘n’ stands for ‘native’);
  3. (1)要想找到到底是哪段具體的代碼占用了如此多的資源,先使用jstack打出當前棧信息到一個文件里, 比如stack.log:

    1

    jstack 52554 > stack.log

    然后使用’jtgrep’腳本把這個進程號為’9757′的java線程在stack.log中抓出來:

    1 jtgrep 9757 stack.log

    其中,’jtgrep’是自己隨便寫的一個shell腳本:

    1 #!/bin/sh
    3 nid=`python -c  "print hex($1)" `
    4 grep  -i $nid $2

    道理很簡單,就是 把’9757′轉換成16進制后,直接grep stack.log;可以看到,被grep出的那個線程的nid=0x3c39,正好是15417的16進制表示。

(2) 通過(windows程序–>計算器),選擇程序員計算器將進程ID轉換成16進制 到dump里面的nid 就可以搜索到

“http-nio-8080-exec-25″ daemon prio=10 tid=0x00007f69686b4800 nid=0x1ce5 waiting on condition [0x00007f698e7cf000]

   java.lang.Thread.State: WAITING (parking)

        at sun.misc.Unsafe.park(Native Method)

        – parking to wait for  <0x0000000777063ec8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)

        at java.util.concurrent.locks.LockSupport.park(Unknown Source)

        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)

        at java.util.concurrent.LinkedBlockingQueue.take(Unknown Source)

        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:104)

        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:32)

        at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)

        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

        at java.lang.Thread.run(Unknown Source)

(二)第二種通過 Java visualMv結合  jconsole.exe    工具即可查看如圖所示;(第一種方式可能更准確一些)

 

三:在Java Visualvm工具里面安裝JTA插件,分析線程dump文件,注意,正常階段的dump文件與非正常時期的Dump文件進行比較更容易分析出問題:
(1)下載:https://java.net/projects/tda/downloads/directory/visualvm
  (2)安裝與使用:
(3)使用:
四:直接通過tda-bin-2.2\bin\tda.sh 來分析導出ThreadDump文件;(在沒有JMX監控的情況下手動查看threadDump信息)
       下載地址:https://java.net/projects/tda/downloads/directory/visualvm
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM