一個線上JVM的CPU資源佔用太高問題的排查

原文:https://www.iteye.com/blog/tyrion-2293369java

 

上午線上某應用的一臺JVM的CPU佔比忽然飆高到192%,而且一直下不來,致使監控一直告警,很久沒處理這種問題了,如今將問題排查步驟總結記錄一下。c++

 

1.經過top命令查看當前機器的CPU使用狀況線程


此時發現若是是Java的進程佔用太高,而且一直下不來,則排查是什麼線程致使佔比太高。以圖中進程舉例,假如發現PID爲31357的Java進程佔CPU比一直很高,則記錄下它的PID日誌

 

2.查看Java進程裏面的線程的佔用狀況blog

top -H -p 31357進程

說明:-H 指顯示線程,-p 是指定進程資源


能夠看到CPU佔用較高的線程,記下他們的PID,假設這裏31357的CPU佔比一直是50%get

 

3.經過jstack命令獲取佔用資源異常的線程棧,可暫時保存到一個文件中查看it

jstack 31357 > jstack.31357.logio


以上能看到指定線程的堆棧信息。

若是想看到關於線程中的鎖的附加信息,能夠加一個-l參數



4.上面方法用於進程正常狀況下的堆棧打印,今天碰到的是用jstack -l命令沒有響應,估計是CPU一直站着不能執行正常的命令,根據提示[The -F option can be used when the target process is not responding]只能放大招了。

jstack -F 「PID」 > jstack.「PID」.txt

吐出的實際日誌結果以下:


發現一大坨線程阻塞了,有用的結果在這裏:

顯然一直在跑的是19576這個線程,一直在執行EXCEL導出的相關方法,問題就出在這裏,下面的任務就是排查這個地方的代碼邏輯了。

jstack命令格式:

jstack [ option ] pid

 

參數說明:

-F jstack [-l] pid沒法響應時,強制打印堆棧

-l l長列表. 打印關於鎖的附加信息,例如屬於java.util.concurrent的ownable synchronizers列表.

-m 混合模式輸出(包括java和本地c/c++片斷)堆棧。

pid: java應用程序的進程號

 

記得沒錯的話這幾個參數是互斥的,不能聯合使用。

 

5.後來搜資料發現用jps命令查看java進程的pid更實用:


 

命令格式

jps [ options ] [ hostid ]

 

參數說明

-m 輸出傳遞給main方法的參數,若是是內嵌的JVM則輸出爲null。

-l 輸出應用程序主類的完整包名,或者是應用程序JAR文件的完整路徑。

-v 輸出傳給JVM的參數。

 

三個參數加在一塊兒顯示更詳細的信息:


發現這些Java進程的啓動參數中開放了JMX的遠程端口,正常狀況下能夠經過jconsole遠程鏈接過去看到JVM的平常參數。好比本地訪問上圖中的pay.war進程:



 



 

相關文章
相關標籤/搜索