相信大家都遇到過,自己的Java應用運作一段時間就當機了或者響應請求特别慢。這時候就需要我們了來找出問題所在了。絕大部分都是代碼問題導緻的。
一、服務當機
如果是服務當機,發生緻命問題導緻程序已經死掉了,那麼已經通路不了了,通常都是CPU問題引起的,程式一般會自己生成javacore檔案,一般生成位置在/root目錄或jar包同目錄下。JavaCore檔案主要儲存的是Java應用各線程在某一時刻的運作的位置,即JVM執行到哪一個類、哪一個方法、哪一個行上。
找到這個檔案,執行指令
gdb java
bt
如果檔案沒有損壞的話可以看到完整的棧調用資訊。就可以定位到問題代碼所在。
我曾經就因為底層調用的一個geo庫出問題,導緻程式直接挂掉,分析core檔案可以清晰的看到native方法的調用。
二、服務響應請求慢
出現這個問題一般都是記憶體溢出,GC線程一直在重複GC,沒有線程來處理使用者請求,或者問題代碼導緻CPU占用過高。
程式崩潰前會生成HeapDump檔案,也可以手動生成,HeapDump是一個二進制檔案,它儲存了某一時刻JVM堆中對象使用情況。
在JVM啟動參數要配置好HeapDump的生成位置和配置列印gc日志。這樣才能排查問題。
先分析GC日志
把gc檔案上傳就好了,就可以看到分析結果。重點關注什麼區域的GC占用最多時間。
離線分析工具:GCViewer 是一款開源的GC日志分析工具。
如果程式記憶體溢出,通過分析gc檔案可以發現程式記憶體占用機會100%而且一直重複GC。
分析HeapDump檔案
1、先找到Java應用的pid
ps -ef | grep java 或者 jps -l 檢視
2、檢視堆記憶體使用量
jmap -heap
3、檢視Java程序中的每一個線程的情況(linux),可以清晰的看到每一個線程的cpu及記憶體使用情況
top -Hp
window下可以借助工具 Process Explorer,
4、列印線程快照資訊,儲存到檔案xxx.txt中友善檢視
jstack > xxx.txt
參考這一篇文章: https://www.jb51.net/article/195797.htm
5、通過top -Hp 看到的線程id是10進制的,我們輸出到xxx.txt中的是16進制,是以需要轉一下,找一個異常線程tid
printf "%x" 假如輸出為 1111
6、在xxx.txt檔案中查找tid為1111的棧資訊,可以看到這個線程在幹什麼,定位到問題代碼。
7、程式當機會自動産生dump檔案,若沒有當機就手動導出dump檔案
jmap -dump:format=b,file=檔案名
桌面分析工具:Eclipse Memory Analyzer,它有windows版的和Linux版的
windows下:把HeapDump檔案放進去就可以了,分析完後,很直覺的看到目前記憶體占用量最高的是某個類的某個參數。持有了多少個對象,這些對象占用了多少記憶體,進而定位到問題代碼。
Linux下:先把Eclipse Memory Analyzer版上傳到伺服器,解壓,假如/home/mat為解壓後路徑,執行指令
/home/mat/ParseHeapDump.sh org.eclipse.mat.api:suspects prg.eclipse.mat.api:overview
org.eclipse.mat.api:top_components
分析完之後會在目前檔案生成結果檔案。下載下傳到本地檢視即可。
以上這篇Java應用/JVM當機排查步驟操作就是小編分享給大家的全部内容了,希望能給大家一個參考,也希望大家多多支援我們。
時間: 2020-09-15