java之CPU過高排查

1.引子

有一次線上CPU過高,在這裡簡單記錄一下排查的步驟。在這裡。先模擬一個java應用CPU過高的程序。一般CPU過高,可能是代碼中有死循環導致。

2.模擬

啟動一個線程,寫一個死循環,這個簡單:

<code>public class Test {
public static void main(String[] args) {

if (args.length == 0) {
System.out.println("運行的時候請輸入參:1 or 2");
return;
}
if (args[0].equalsIgnoreCase("1")) {
startThread1();
}
if (args[0].equalsIgnoreCase("2")) {
startThread2();
}
}

public static void startThread1() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
String a = new String("deadThread");
\t\t\t\t\t\t\t\t\t
}
}
});
thread.setName("deadThread");
thread.start();
}


public static void startThread2() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
List<string> list = new ArrayList<>();
while (true) {
String a = new String("OOMThread");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}

list.add(a);

}
}
});
thread.setName("OOMThread");
thread.start();
}
}/<string>/<code>

上面程序很簡單,輸入參數1,表示啟動一個線程。循環輸出一個字符串。

3.上機測試

首先編譯一下:

<code>javac test.java  /<code>
java之CPU過高排查

javac test.java

然後運行該程序:

<code>java Test 1/<code>


java之CPU過高排查

java Test 1

4排查問題

1首先,使用top命令看一下那個進程CPU過高


java之CPU過高排查

top

2.記錄一下pid號:64644,然後Ctrl+C,停止。輸入:top -H -p 64644


java之CPU過高排查

top -H -p 64644

這樣到java進程中那個線程導致的CPU過高。拿到PID:64659。

由於java棧中顯示的pid是16進制的。所以這裡需要將十進制轉化為16進制:

<code>printf '%x\\n' 64659  /<code>


java之CPU過高排查

printf '%x\\n' 64659

3.使用jstack命令查看

<code>jstack 64644/<code>


java之CPU過高排查

敲完之後,會顯示很多內容,這個時候就用到了,剛才將十進制轉化為16進制的:fc93了,使用grep過濾一下


java之CPU過高排查

jstack 64644 | grep -A10 fc93

注:這-A10表示搜索到fc93的地方,向下多展示10行。如下圖。

java之CPU過高排查

到此,就找到了導致CPU過高的代碼。at Test$1.run(test.java:31)。然後去檢查自己的代碼。


5.後續

記錄一下,排查問題的步驟。下次介紹一下,OOM的排查。


分享到:


相關文章: