生產環境出現CPU占用過高,請談談你的分析思路和定位


模擬問題代碼

import java.util.Random;
​
public class HighCPUDemo{
  public static void main(String[] args) {
​
        while (true){
            System.out.println(new Random(999999));
        }
}
}

當編譯運行上面代碼則會循環打印,對CPU占用較高

下面演示全部過程,首先運行代碼

[root@izuf67vu7do989lgqvknozz ~]# javac HighCPUDemo.java
[root@izuf67vu7do989lgqvknozz ~]# java HighCPUDemo

此時,代碼運行起來,后台在循環輸出隨機數,CPU占用過高

問題分析:結合Linux和jdk一塊分析

代碼運行起來后可用top查看占用CPU最高的進程或者jps命令查看是哪些運行的java進程

1、top命令-找到CPU占比最高的進程

 

找到占用最高的進程是java進程,進程id:11849

2、ps -ef或者jps定位

得知是一個怎么樣的后台程序給我們惹事

[root@izuf67vu7do989lgqvknozz ~]# jps -l
11861 sun.tools.jps.Jps
11849 HighCPUDemo
[root@izuf67vu7do989lgqvknozz ~]# ps -ef|grep java|grep -v grep
root     11849 11636 14 10:02 pts/0    00:00:13 java HighCPUDemo

以上兩種方式都可以查看java進程,找到了java進程,接下來就要定位到具體的線程或者代碼

公式:

ps -mp 進程 -o THREAD, tid, time

參數解釋

-m 顯示所有的線程
-p pid 進程使用cpu的時間
-o 該參數后是用戶自定義格式

3、定位具體線程

輸入公式,顯示出下面的結果,找到占用CPU最高的那個線程,找出線程id-->TID--->11850

[root@izuf67vu7do989lgqvknozz ~]# ps -mp 11849 -o THREAD,tid,time
USER     %CPU PRI SCNT WCHAN  USER SYSTEM   TID     TIME
root     13.8   -    - -         -      -     - 00:00:24
root      0.0  19    - futex_    -      - 11849 00:00:00
root     13.5  19    - n_tty_    -      - 11850 00:00:23
root      0.0  19    - futex_    -      - 11851 00:00:00
root      0.0  19    - futex_    -      - 11852 00:00:00
root      0.0  19    - futex_    -      - 11853 00:00:00
root      0.0  19    - futex_    -      - 11854 00:00:00
root      0.0  19    - futex_    -      - 11855 00:00:00
root      0.0  19    - futex_    -      - 11856 00:00:00
root      0.0  19    - futex_    -      - 11857 00:00:00
root      0.0  19    - futex_    -      - 11858 00:00:00

 

4、將需要的線程id轉換為16進制格式(英文小寫格式)

公式

printf "%x\n"有問題的線程ID

下面是運算結果

[root@izuf67vu7do989lgqvknozz ~]# printf "%x\n" 11850
2e4a

即11850的16進制是2e4a

5、找出具體的問題代碼

公式

jstack 進程id | grep tid(16進制線程id小寫英文)-A60
顯示出有問題的代碼
[root@izuf67vu7do989lgqvknozz ~]# jstack 11849 |grep 2e4a -A60
"main" #1 prio=5 os_prio=0 tid=0x00007f8968008800 nid=0x2e4a runnable [0x00007f8970626000]
   java.lang.Thread.State: RUNNABLE
        at java.io.FileOutputStream.writeBytes(Native Method)
        at java.io.FileOutputStream.write(FileOutputStream.java:326)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
        - locked <0x00000000ecd6b900> (a java.io.BufferedOutputStream)
        at java.io.PrintStream.write(PrintStream.java:482)
        - locked <0x00000000ecd63d70> (a java.io.PrintStream)
        at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
        at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
        at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
        - locked <0x00000000ecd63d28> (a java.io.OutputStreamWriter)
        at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
        at java.io.PrintStream.newLine(PrintStream.java:546)
        - eliminated <0x00000000ecd63d70> (a java.io.PrintStream)
        at java.io.PrintStream.println(PrintStream.java:824)
        - locked <0x00000000ecd63d70> (a java.io.PrintStream)
        at HighCPUDemo.main(HighCPUDemo.java:7)"VM Thread" os_prio=0 tid=0x00007f896806d000 nid=0x2e4b runnable
​
"VM Periodic Task Thread" os_prio=0 tid=0x00007f89680b5800 nid=0x2e52 waiting on condition
​
JNI global references: 9
 

 從結果上顯示,問題代碼出現在at HighCPUDemo.main(HighCPUDemo.java:7),也就是那句輸出語句。

以上就是具體的案例分析,


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM