面試問題---JAVA程式CPU占用過高怎麼定位
今天一個電話面試問了這個問題。回來查了下答案,自己也順帶操作一遍,做個記錄。之前隻知道jstack工具可以檢視線程狀态這些。比如死鎖這些,主要是之前不知道top -H -p pid這個指令的使用,這指令可以看到程序下面線程資訊,拿到線程ID,然後再結合jstack指令使用就可以解決這個問題了。下面記錄一下具體的操作步驟:
1.打個jar包丢到機器上運作
package com.nijunyang.test;
public class TestApplication {
public static void main(String[] args) {
for (int i = 0; i < 50; i++) {
new Thread(()->test()).start();
}
}
public static void test() {
while (true) {
int a = 1 + 6;
System.out.println(a);
}
}
}
使用這個maven插件 打包jar
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.nijunyang.test.TestApplication</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
- java -jar test-0.0.1-SNAPSHOT-jar-with-dependencies.jar 運作程式
一直在輸出
3.top |grep java 或者 jps指令找到java程序的pid(6167)
4. top -H -p pid 以線程的形式檢視該程序 top -H -p 6167
因為我們程式是起了50個線程 是以這裡就會展示這個程序中的所有線程呢
5.前面的線程ID是10進制的,,需要轉換成16進制,,因為等下在jstack指令取出來的線程ID是16進制的:這裡就随便選一個線程ID 去轉換了,真實環境肯定是選擇CPU占用率最高的那個線程,echo "obase=16;6219" | bc
6.jstack 6167 >threadInfo.txt 資訊輸出到檔案 然後檢視。也可以直接在指令裡面檢視
7.檔案中查找184b的線程ID資訊,就可以找到是哪個線程導緻的記憶體占用過高,同時也能看到具體的代碼位置
原文位址
https://www.cnblogs.com/nijunyang/p/13040511.html