面試問題---JAVA程式CPU佔用過高怎麼定位
阿新 • • 發佈:2020-07-23
今天一個電話面試問了這個問題。回來查了下答案,自己也順帶操作一遍,做個記錄。之前只知道jstack工具可以檢視執行緒狀態這些。比如死鎖這些,主要是之前不知道top -H -p pid這個命令的使用,這命令可以看到程序下面執行緒資訊,拿到執行緒ID,然後再結合jstack命令使用就可以解決這個問題了。下面記錄一下具體的操作步驟:
1.打個jar包丟到機器上執行
1 package com.nijunyang.test; 2 3 4 5 public class TestApplication { 6 7 public static void main(String[] args) {8 for (int i = 0; i < 50; i++) { 9 new Thread(()->test()).start(); 10 } 11 12 } 13 14 public static void test() { 15 while (true) { 16 int a = 1 + 6; 17 System.out.println(a); 18 } 19 } 20 }
使用這個maven外掛 打包jar
1<plugin> 2 <groupId>org.apache.maven.plugins</groupId> 3 <artifactId>maven-assembly-plugin</artifactId> 4 <configuration> 5 <archive> 6 <manifest> 7 <mainClass>com.nijunyang.test.TestApplication</mainClass> 8</manifest> 9 </archive> 10 <descriptorRefs> 11 <descriptorRef>jar-with-dependencies</descriptorRef> 12 </descriptorRefs> 13 </configuration> 14 <executions> 15 <execution> 16 <id>make-assembly</id> 17 <phase>package</phase> 18 <goals> 19 <goal>single</goal> 20 </goals> 21 </execution> 22 </executions> 23 </plugin>
2. 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資訊,就可以找到是哪個執行緒導致的記憶體佔用過高,同時也能看到具體的程式碼位置