Jvm FullGC 如何排查?


使用場景

我們在使用系統時,有時請求和響應會變得特別慢,系統也變得很卡。

有可能是FullGC的問題,可以逐步地進行排查。

使用jps和top確定進程號pid

jps可以列出正在運行的jvm進程,並顯示jvm執行主類名稱( main()函數所在的類),以及進程id。

命令如下:

jps -l

結果如下:

而top命令查看cpu使用情況,獲取對應的進程號pid:

top

如下所示,發現進程號pid為72的進程占用了近100%的cpu:

jstat檢查進程號的gc,是否發生fullGC:

jstat,就是JVM Statistics Monitoring Tool.
下面這個命令的意思是每隔2s顯示pid為72的進程的GC情況:

jstat -gcutil 72 2000

結果如下:

我們主要觀察FGC這個參數,可以發現,每隔幾秒,FGC的次數就會變多。

具體的含義如下:

參數含義:
S0 : Heap 上的 Survivor space 0 段已使用空間的百分比
S1 : Heap 上的 Survivor space 1 段已使用空間的百分比
E : Heap 上的 Eden space 段已使用空間的百分比
O : Heap 上的 Old space 段已使用空間的百分比
P : Perm space 已使用空間的百分比
YGC :從程序啟動到采樣時發生 Young GC 的次數
YGCT : Young GC 所用的時間 ( 單位秒 )
FGC :從程序啟動到采樣時發生 Full GC 的次數
FGCT : Full GC 所用的時間 ( 單位秒 )
GCT :用於垃圾回收的總時間 ( 單位秒 ) 

查看在這個進程中消耗cpu最多的線程

命令如下:

top -H -p 72

可以查看在72這個進程的各個線程
-H表示 Threads-mode operation,線程模式,展示各個線程。
-p表示 Monitor-PIDs mode,監控模式,通過進程id監控進程。
詳情見: https://blog.csdn.net/qq_31302009/article/details/77803006

結果如下,可以看到消耗cpu最多的線程號80和79:

  • 計算線程號的16進制結果
printf %x 79

將線程號80和79分別轉換成16進制,將結果4f和50記下來,可以在后面的dump文件搜索。

jstack分析線程堆棧,並保存結果

  • 根據進程號,輸出進程的線程dump文件。

以下命令是將進程號為72的dump文件,輸出到 /tmp/dump_file這個路徑,也可以是其他任意路徑。

> 表示將命令執行的結果保存到文件並覆蓋原文件的內容。

jstack 72 > /tmp/dump_file
  • 打開dump文件,根據之前printf %x計算得到的16進制結果搜索。

比如printf %x 79 計算得到的結果為4f,可以通過4f進行搜索,也可以用0x4f搜索。

(注:如果不想保存文件,也可以直接用命令

jstack -l 72 | grep 0x4f -C 10 

jstack -l顯示線程堆棧詳情,grep匹配關鍵字0x4f,-C 10表示顯示關鍵字前后10行。)

主要看nid。 nid,意思是 native thread id. 每一個nid對應於linux下的一個tid。
jstack中的nid是十六進制數。
搜索找到 nid=0x4f 的線程,就可以拿到線程的堆棧,找到出問題的代碼了。

jmap分析進程的內存使用情況

  • jmap分析進程72的內存使用情況,並保存dump文件

jmap,就是Java Memory Map.

jmap -histo 72 > pid72.log

以上命令中的 pid72.log是文件名稱,也可以改用其他名稱。而72是進程號。

查到 pid72.log 文件,內存的使用情況如下:

參數的含義如下:

說明:

#instance 是對象的實例個數
#bytes 是總占用的字節數
class name 對應的就是 Class 文件里的 class 的標識
B 代表 byte
C 代表 char
D 代表 double
F 代表 float
I 代表 int
J 代表 long
Z 代表 boolean
前邊有 [ 代表數組, [I 就相當於 int[]
對象用 [L+ 類名表示 

jhat分析jmap生成的堆內存快照

jhat,就是JVM Heap Analysis Tool,虛擬機堆內存快照分析工具。
jhat,可以用來分析jmap生成的堆內存文件。
除了jhat,也可以用專業用於分析dump文件的Memory Analyzer(MAT)等工具。

jmap -dump:format=b,file=a.hprof 72
jhat -J-Xmx512M a.hprof

a.hprof是文件名稱,也可以改用其他命名。

結果如下:

屏幕顯示"Server is ready."的提示后,用戶在瀏覽器中輸入http://要訪問的ip:7000/,
比如 http://localhost:7000/ 就可以看到分析結果了。

分析結果默認是以包為單位進行分組顯示,分析內存泄漏問題主要會使用到其中的 "Heap Histogram",可以找到內存中總量最大的對象。

參考資料

《深入理解java虛擬機》
https://blog.csdn.net/weixin_34320159/article/details/91553350
https://www.cnblogs.com/kongzhongqijing/articles/3621223.html
https://www.cnblogs.com/kingszelda/p/9034191.html


免責聲明!

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



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