[轉]Java線上問題排查思路及Linux常用問題分析命令學習文章

Java線上問題排查思路及Linux常用問題分析命令學習

前言

之前線上有過一兩次OOM的問題,但是每次定位問題都有點手足無措的感覺,剛好利用星期天,以測試環(huán)境為模版來學習一下Linux常用的幾個排查問題的命令。?

也可以幫助自己在以后的工作中快速的排查線上問題。

jmap命令

jmap -heap pid 輸出當前進程 JVM 堆新生代、老年代、持久代等請情況,GC 使用的算法等信息?

jmap -histo:live {pid} | head -n 10 輸出當前進程內存中所有對象包含的大小??

jmap -dump:format=b,file=/usr/local/logs/gc/dump.hprof {pid} 以二進制輸出檔當前內存的堆情況,然后可以導入 MAT 等工具進行

1、 jmap -heap pid

輸出當前進程JVM堆新生代、老年代、持久代等情況,GC使用的算法等信息。?

2、jmap -histo:live {pid} | head -n 10 輸出當前進程內存中所有對象包含的大小

輸出當前進程內存中所有對象實例數(shù) (instances) 和大小 (bytes), 如果某個業(yè)務對象實例數(shù)和大小存在異常情況,可能存在內存泄露或者業(yè)務設計方面存在不合理之處。?

jmap -dump:

命令如下:?

mkdir logs?

jmap -dump:format=b,file=/tmp/logs/dump.hprof {pid}

-dump:formate=b,file= 以二進制輸出當前內存的堆情況至相應的文件,然后可以結合 MAT 等內存分析工具深入分析當前內存情況。?

也可以通過JVM參數(shù)配置OOM時自動dump當前內存鏡像文件。 -XX:+HeapDumpOnOutOfMemoryError 和-XX:HeapDumpPath所代表的含義就是當程序出現(xiàn)OutofMemory時,將會在相應的目錄下生成一份dump文件,而如果不指定選項-XX:HeapDumpPath則在當前目錄下生成dump文件。?

確保應用發(fā)生 OOM 時 JVM 能夠保存并 dump 出當前的內存鏡像。?

當然,如果你決定手動 dump 內存時,dump 操作占據(jù)一定 CPU 時間片、內存資源、磁盤資源等,因此會帶來一定的負面影響。?

此外,dump 的文件可能比較大 , 一般我們可以考慮使用 zip 命令對文件進行壓縮處理,這樣在下載文件時能減少帶寬的開銷。?

下載 dump 文件完成之后,由于 dump 文件較大可將 dump 文件備份至制定位置或者直接刪除,以釋放磁盤在這塊的空間占用。

dump 日志分析

MAT(Memory Analyzer Tool),一個基于 Eclipse 的內存分析工具,是一個快速、功能豐富的 JAVA heap 分析工具,它可以幫助我們查找內存泄漏和減少內存消耗。?

使用內存分析工具從眾多的對象中進行分析,快速的計算出在內存中對象的占用大小,看看是誰阻止了垃圾收集器的回收工作,并可以通過報表直觀的查看到可能造成這種結果的對象。?

具體可以參考:Java內存分析工具MAT(Memory Analyzer Tool)安裝使用實例 : https://blog.csdn.net/jin_kwok/article/details/80326088?和?基于Java內存dump文件分析解決內存泄漏問題 : http://www.itdecent.cn/p/2cf7169ba1c4

jstack命令

printf '%x\n' tid --> 10 進制至 16 進制線程 ID(navtive 線程) %d 10 進制?

jstack pid | grep tid -C 30 --color ps -mp 8278 -o THREAD,tid,time | head -n 40

某 Java 進程 CPU 占用率高,我們想要定位到其中 CPU 占用率最高的線程。?

(1) 先利用top命令找到CPU占用高的進程pid?

也可以通過ps -ef | grep 應用名 來快速定位自己應用的pid?

顯示pid:29080?

(2) 利用 top 命令可以查出占 CPU 最高的線程 pid (先找到該pid 29080下所有的線程數(shù)據(jù))?


可以看到占用cpu資源最高的為29173

(3) 占用率最高的線程 ID 為29173,將其轉換為 16 進制形式 (因為 java native 線程以 16 進制形式輸出)

printf '%x\n' 29173?

(4) 利用 jstack 打印出 java 線程調用棧信息?

jstack 29080 | grep '0x71f5' -A 50 --color?

可以看到這個線程是在做kafka相關的操作。因為這是測試,所以并不是因為CPU真的占用過高的情況。?

更多內容也可以參考:?

如何使用jstack分析線程狀態(tài) : http://www.itdecent.cn/p/6690f7e92f27?

通過jstack與jmap分析一次線上故障: https://www.cnblogs.com/kingszelda/p/9034191.html

jinfo命令

jinfo可以用來查看正在運行的java運用程序的擴展參數(shù)。?

查看pid對應的JVM參數(shù),可以到?PerfMa : http://xxfox.perfma.com/jvm/check?校驗參數(shù)的正確性?

jinfo -flags pid?

拿到Command line后面的配置參數(shù)到perfma中驗證查詢:?

這里面好多功能可以去使用。

jstat命令

jstat:Java Virtual Machine statistics monitoring tool JDK自帶的一個輕量級小工具。

jstat顯示GC執(zhí)行的情況

jstat -gc 12538 5000?

即會每5秒一次顯示進程號為12538的java進成的GC情況

說明:?

S0C、S1C、S0U、S1U:Survivor 0/1區(qū)容量(Capacity)和使用量(Used)?

EC、EU:Eden區(qū)容量和使用量?

OC、OU:年老代容量和使用量?

PC、PU:永久代容量和使用量?

YGC、YGT:年輕代GC次數(shù)和GC耗時?

FGC、FGCT:Full GC次數(shù)和Full GC耗時?

GCT:GC總耗時

顯示內容說明如下(部分結果是通過其他其他參數(shù)顯示的,暫不說明):?

S0C:年輕代中第一個survivor(幸存區(qū))的容量 (字節(jié))?

S1C:年輕代中第二個survivor(幸存區(qū))的容量 (字節(jié))?

S0U:年輕代中第一個survivor(幸存區(qū))目前已使用空間 (字節(jié))?

S1U:年輕代中第二個survivor(幸存區(qū))目前已使用空間 (字節(jié))?

EC:年輕代中Eden(伊甸園)的容量 (字節(jié))?

EU:年輕代中Eden(伊甸園)目前已使用空間 (字節(jié))?

OC:Old代的容量 (字節(jié))?

OU:Old代目前已使用空間 (字節(jié))?

PC:Perm(持久代)的容量 (字節(jié))?

PU:Perm(持久代)目前已使用空間 (字節(jié))?

YGC:從應用程序啟動到采樣時年輕代中gc次數(shù)?

YGCT:從應用程序啟動到采樣時年輕代中gc所用時間(s)?

FGC:從應用程序啟動到采樣時old代(全gc)gc次數(shù)?

FGCT:從應用程序啟動到采樣時old代(全gc)gc所用時間(s)?

GCT:從應用程序啟動到采樣時gc用的總時間(s)?

總結

一般分析CPU或者內存異常情況可以通過以下幾步:

查看日志

查看CPU情況

查看TCP情況

查看java線程,jstack

查看java堆,jmap

通過MAT分析堆文件,尋找無法被回收的對象

參考:?

Java線上問題排查思路與工具使用 : https://blog.csdn.net/GitChat/article/details/79019454

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容