找出java程式碼中佔用cpu過多問題
阿新 • • 發佈:2019-02-14
當有java程序佔用過多CPU時,可能是邏輯出現的問題。如何排查問題所在呢?
1. 使用top工具列出所有程序,shitf + p 列出CPU佔用率較高程序
2. 找到問題程序號,使用top -H -p pid列出程序的所有執行緒
3. 然後shift + p 按照CPU使用率排序
4. 找出問題程序號,打印出其16進位制值,printf "%x", ppid,比如是:76a3
5. jstack pid > t.dat 記錄執行緒堆疊,vi 開啟找到76a3的執行緒號,結合原始碼定位問題
下面使用一個死迴圈的例子進行講解:
public class Main { public static void main(String[] args) throws Exception { Thread t1 = new Thread(new T1()); t1.setName("tone"); Thread t2 = new Thread(new T2()); t2.setName("ttwo"); t1.start(); t2.start(); } public static class T1 implements Runnable { public void run() { int a = 0; while (true) { a++; try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static class T2 implements Runnable { public void run() { long a = 0L; while (true) { a++; } } } }
上面的程式碼啟動兩個執行緒,執行緒T1會佔用少量CPU,執行緒T2會佔滿一個CPU。
首先我們通過top列出程序,按照cpu使用率排序(shift + p)
可以看出出問題的程序號是30358
然後使用 top -H -p 30358 得到如下結果,然後使用shitf + p按照cpu使用率排序
這裡可以看到執行緒為30371佔用太多CPU,此執行緒有問題
接下來使用jstack 30358 > t.dat 記錄執行緒堆疊
使用python打印出出30371的16進位制值 (print("0x" % 30371結果為76a3
線上程堆疊中找到76a3程序,然後仔細檢視堆疊資訊
這裡可以看到ttwo執行緒名,執行到了Main的31行,此時我們在去原始碼中仔細檢視附近的邏輯,問題一目瞭然