1. 程式人生 > >Linux中如何精準定位JVM執行緒CPU過高

Linux中如何精準定位JVM執行緒CPU過高

    此文提供一種方法來快速定位Linux中JVM的執行緒CPU過高的問題。執行在Linux上的JVM的一個核心概念是:Java執行緒通過native threads實現,這導致Java中的每個執行緒對應著一個獨立的Linux程序。
    仍然需要生成jvm程序的thread dump data,便於與Linux top命令輸出關聯。步驟如下:
    1)執行top命令,或使用-H選項(顯示所有執行緒),找到相關的高CPU的PID
    2)生成thread dump 快照(kill -3 PID)。
    3)將top命令輸出PID轉換為HEX格式(16進位制)
    4)在thread dump data中搜索nid=<Hex PID>
    5)分析受影響的thread和stack trace,精確定位程式碼。
top output sample
PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME COMMAND
...........
22111 userWLS 9 0 86616 84M 26780 S 0.0 40.1 0:00 java

Thread Dump output sample Thread as per the above search criteria nid=0x565F

"ExecuteThread: '0' for queue: 'default'" daemon prio=1 tid=0x83da550 nid=0x565F waiting on monitor [0x56138000..0x56138870]
  at java.util.zip.ZipFile.getEntry(Native Method)
  at java.util.zip.ZipFile.getEntry(ZipFile.java:172)
  at java.util.jar.JarFile.getEntry(JarFile.java:269)
  at java.util.jar.JarFile.getJarEntry(JarFile.java:252)
  at sun.misc.URLClassPath$JarLoader.getResource(URLClassPath.java:989)
  at sun.misc.URLClassPath$JarLoader.findResource(URLClassPath.java:967)
  at sun.misc.URLClassPath.findResource(URLClassPath.java:262)
  at java.net.URLClassLoader$4.run(URLClassLoader.java:763)
  at java.security.AccessController.doPrivileged(AccessController.java:224)
  at java.net.URLClassLoader.findResource(URLClassLoader.java:760)
  at java.lang.ClassLoader.getResource(ClassLoader.java:444)
  at java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:504)
  ............................................  

這裡可以參考下:http://www.cnitblog.com/tjitty/archive/2010/07/12/67429.html文章,直接檢視主程序下所有執行緒CPU使用情況。

    pidstat  -T CHILD -r 2 5  //表示所有子程序在2到5秒內,記憶體的使用狀況,只有minflt/s或majflt/s非零的程序才會被列出來。
-T 後邊跟 CHILD 表示全域性統計所選程序以及其子程序佔用cpu或記憶體的情況如果跟TASK 表示,所有獨立程序,預設選項就是TASK, 還可以跟ALL是CHILD和TASK加起來的結果. 值得注意的是,全域性統計程序以及子程序並不是pidstat所有選項都可用的,並且也不適用於某個時間段:當程序執行完畢或者程序被中止後才會收集到相關的統計資料。