Jvm故障問題排查以及Jvm調優總結

Jvm故障問題排查以及Jvm調優總結java

 

爲了學習jvm故障問題的排查,寫了一個例子來驗證,在我以前服務器上部署的一個音樂網站的項目里加了一段代碼。git

輕語音樂網站項目地址:https://github.com/Linliquan/springboot-musicgithub

 

以下:spring

在一個音樂搜索方法getSongRearch中加了一個for循環,循環一億次建立HashMap對象。springboot

 

項目啓動部署後,在頁面上模糊搜索歌曲「你」,發現搜索緩慢。服務器

 

 

大約十幾秒後才搜索出來jvm

 

 打印的日誌:學習

 

 排查過程:網站

1. 使用 ps -ef | grep java 命令找到相應的進程pid,pid = 24314spa

 

 2. 使用 top 命令,查看cup佔用狀況。如圖,id爲24314的進程,cpu佔用率爲99%

 

3. 使用 top -Hp pid 命令,查看 pid=24314 進程下的各個線程cpu佔用狀況。

 

 4. 使用 printf  "%x"  tid 命令,將佔用cpu比較高的線程的 tid = 24335 轉化爲十六進制,34335的十六進制爲 5f0f 

 

 5. 使用 jstack pid| grep 十六進制 -A20 命令,如 jstack 24314 | grep 5f0f -A20 打印20行線程的堆棧信息。

grep -A是顯示匹配後和它後面的n行,-B是顯示匹配行和它前面的n行,-C是匹配行和它先後各n行。

 

如圖能夠看到,MusicLinkController 的 getSongRearch 方法的第180行代碼有問題,而且線程的狀態爲RUNNABLE。

 

這樣就能夠找出相應有問題的代碼

 

 

進一步排查:

1.使用 jmap -histo pid | head 命令,查看堆內存狀況

 

 

2.使用 jmap -heap pid,查看堆內存狀況

 

 

3.使用 jstat -gc pid 命令,查看各個區內存使用狀況

 

4.使用 jstat -gcutil 24314命令,查看各區容量使用率,如圖老年代使用率爲96.6%。

 

5.使用jstat -gc 24314 100 10,每隔100ms打印一次,打印5次

 

S0C:第一個倖存區的大小
S1C:第二個倖存區的大小
S0U:第一個倖存區的使用大小
S1U:第二個倖存區的使用大小
EC:伊甸園區的大小
EU:伊甸園區的使用大小
OC:老年代大小
OU:老年代使用大小
MC:方法區大小
MU:方法區使用大小
CCSC:壓縮類空間大小
CCSU:壓縮類空間使用大小
YGC:年輕代垃圾回收次數
YGCT:年輕代垃圾回收消耗時間
FGC:老年代垃圾回收次數
FGCT:老年代垃圾回收消耗時間
GCT:垃圾回收消耗總時間

年輕帶分三個區:1個E,2個S區。

1.全部對象在E區分配內存,E區和2個S區初始化爲空
2.E區滿後,對象沒法分配內存,觸發GC
3.第一次GC,就是把E區活對象移到S0區
4.第二次GC,E區和S0區的活對象合併,往S1區轉移
5.第三次GC,E區和S1區的活對象合併,往S0區轉移,此後重複步驟:4,5
6.若是活對象存活時間達到必定長度或者根據動態年齡斷定法,則轉移到年老代。

由下圖中也能夠看得出來

 

 

6.設置jvm參數

-Xms :初始堆大小,-Xmn:最大堆大小

 

 

7. 使用jmap -heap pid命令,可見新生代爲200M,老年代爲400M,且爲1:2。

 

 

jvm參數

相關文章
相關標籤/搜索