深入瞭解JVM之線上問題排查及工具使用(五)

一、前言

    線上問題排查是每一個程序員都應該具備的能力,這一篇文章將從問題分類、常用命令和工具、具體案例分析這幾個方面進行說明。

二、常用工具和命令

jps,JVM Process Status Tool,用來查看基於HotSpot的JVM裏面中,所有具有訪問權限的Java進程的具體狀態, 包括進程ID,進程啓動的路徑及啓動參數等等,與unix上的ps類似,只不過jps是用來顯示java進程,可以把jps理解爲ps的一個子集。
jstat,JVM Statistics Monitoring Tool,jstat是用於監視虛擬各種運行狀態信息的命令行工具,它可以顯示本地或者遠程虛擬機進程中的類裝載、內存、垃圾收集、JIT編譯等運行數據。
jinfo,Configuration info for java,命令的作用是實時的查看和調整虛擬機的參數。
jmap,Memory Map for java,生成虛擬機的內存轉儲快照(heapdump)
jhat,JVM Heap Dump Browser,用於分析heapdump文件,它會建立一個Http/HTML服務器,讓用戶可以在瀏覽器上查看分析結果
jstack,Stack Trace for java,顯示虛擬機的線程快照。
使用–help,查看命令具體使用

常用:
jps -v
jstat -gc 118694 500 5 
jmap -dump:live,format=b,file=dump.hprof 29170
jmap -heap 29170
jmap -histo:live 29170 | more
jmap -permstat 29170
jstack -l 29170 |more
jstack 31177 > /home/tengfei.fangtf/dump17
grep java.lang.Thread.State dump17 | awk '{print $2$3$4$5}'
| sort | uniq -c

關於命令的詳細說明可以查看jvm系列五:監測命令(jvisualvm jps jstat jmap jhat jstack jinfo)及dump堆內存快照分析

三、問題分類以及處理策略

1、業務日誌

如果應用系統出現異常,一般都會在業務日誌中體現

統計當天業務日誌中ERROR出現數量:egrep ERROR --color logname | wc -l  ,如果錯誤數量過大,一般都是有問題的

查看日誌中ERROR後10行具體報錯:egrep -A 10 ERROR logname | less ,或 -C 10 查看ERROR前後10行日誌

sed -n '/起始時間/,/結束時間/p' 日誌文件

sed -n '/2018-12-06 00:00:00/,/2018-12-06 00:03:00/p' logname  # 查詢三分鐘內的日誌,後再跟grep 過濾相應關鍵字

sed -n '/2018-12-06 08:38:00/,$p' logname  |  less # 查詢指定時間到當前日誌
2.死鎖

死鎖原因是兩個或者多個線程相互等待資源。現象通常是出現線程hung住。更嚴重會出現線程數暴漲,系統出現api alive報警等。查看死鎖最好的方法就是分析當時的線程棧。

用到的命令:
jps -v
jstack -l pid

通過《手寫死鎖》文中的例子啓動了一個發生死鎖的進程,執行上述命令,可以定位到引發死鎖的代碼。
在這裏插入圖片描述

3.OOM相關

發生OOM問題一般服務都會crash,業務日誌會有OutOfMemoryError。

OOM一般都是出現了內存泄露,須要查看OOM時候的jvm堆的快照,假設配置了-XX:+HeapDumpOnOutOfMemoryError, 在發生OOM的時候會在-XX:HeapDumpPath生成堆的dump文件。結合MAT,能夠對dump文件進行分析。查找出發生OOM的原因。

ps:
1、server的內存一般較大,所以要保證server的磁盤空間大於內存大小
2、另外手動dump堆快照。能夠使用命令jmap -dump:format=b,file=file_name pid 或者kill -3 pid

常用命令:
$ jhat -J-Xmx512m dump.hprof

JVM配置:
-Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Users\Administrator\Desktop

分析同樣一個dump快照,MAT需要的額外內存比jhat要小的多的多,所以建議使用MAT來進行分析。

4.線程block、線程數暴漲

線程block問題通常是等待io、等待網絡、等待監視器鎖等造成,可能會導致請求超時、造成造成線程數暴漲導致系統502等。
假設出現這樣的問題,主要是關注jstack 出來的BLOCKED、Waiting on condition、Waiting on monitor entry等狀態信息。
假設大量線程在“waiting for monitor entry”:可能是一個全局鎖堵塞住了大量線程。
假設短時間內打印的 thread dump 文件反映。隨着時間流逝。waiting for monitor entry 的線程越來越多,沒有降低的趨勢,可能意味着某些線程在臨界區裏呆的時間太長了,以至於越來越多新線程遲遲無法進入臨界區。
假設大量線程在“waiting on condition”:可能是它們又跑去獲取第三方資源,遲遲獲取不到Response,導致大量線程進入等待狀態。
假設發現有大量的線程都處在 Wait on condition,從線程堆棧看,正等待網絡讀寫,這可能是一個網絡瓶頸的徵兆,由於網絡堵塞導致線程無法運行。

jstack -l pid |wc -l
jstack -l pid |grep "BLOCKED"|wc -l
jstack -l pid |grep "Waiting on condition"|wc -l

四、參考

java線上服務問題排查總結

jvm系列五:監測命令(jvisualvm jps jstat jmap jhat jstack jinfo)及dump堆內存快照分析

JVM學習之jstat使用方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章