1. 程式人生 > 實用技巧 >JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

前言

後文會從 Windows、Linux 兩個系統來做示例展示,有人會有疑問了:為什麼要說Windows版的 ? 目前市面上還是有很多 Windows 伺服器的,應用於傳統行業、政府結構、醫療行業 等等;兩個系統下的情況都演示下,有備無患

後文中用到了兩個工具:Processor Explorer、MAT,它們是什麼,有什麼用,怎麼用,本文不做介紹

cpu 100%

下面的示例中, cpu 的佔有率沒到 100%,只是比較高,但是排查方式是一樣的,希望大家不要鑽牛角尖

Windows

1、找到 cpu 佔有率最高的 java 程序號

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

PID:20260

2、根據程序號找到 cpu 佔有率最高的執行緒號

雙擊剛剛找到的 java 程序

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

執行緒號:15900,轉成十六進位制:3e1c

3、利用jstack生成虛擬機器中所有執行緒的快照

命令:jstack -l {pid} > {path}

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

檔案路徑:D:\20260.stack

4、執行緒快照分析

我們先瀏覽下快照內容

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

內容還算比較簡潔,執行緒快照格式都是統一的,我們以一個執行緒快照簡單說明下

"main" #1 prio=5 os_prio=0 tid=0x0000000002792800 nid=0x3e1c runnable [0x00000000025cf000]

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

我們前面找到佔 cpu 最高的執行緒號: 15900 ,十六進位制: 3e1c ,用3e1c去快照檔案裡面搜一下

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

自此,找到問題

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

Linux

排查方式與 Windows 版一樣,只是命令有些區別

1、找到 cpu 佔有率最高的 java 程序號

使用命令:top -c顯示執行中的程序列表資訊,shift + p使列表按 cpu 使用率排序顯示

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

PID = 2227的程序,cpu 使用率最高

2、根據程序號找到 cpu 佔有率最高的執行緒號

使用命令:top -Hp {pid},同樣shift + p可按 cpu 使用率對執行緒列表進行排序

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

PID = 2228的執行緒消耗 cpu 最高,十進位制的2228轉成十六進位制8b4

3、利用jstack生成虛擬機器中所有執行緒的快照

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

4、執行緒快照分析

分析方式與 Windows 版一致,我們可以把2227.stack下載到本地進行分析,也可直接在 Linux 上分析

在 Linux 上分析,命令:cat 2227.stack |grep '8b4' -C 5

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

至此定位到問題

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

不管是在 Windows 下,還是在 Linux 下,排查套路都是一樣的

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

記憶體洩露

同樣的,Windows、Linux 各展示一個示例

Windows

1、找到記憶體佔有率最高的程序號PID

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

第一眼看上去,idea記憶體佔有率最高,因為我是以 idea 啟動的 java 程序;idea 程序我們無需關注,我們找到記憶體佔有率最高的 java 的 PID:10824

2、利用jmap生成堆轉儲快照

命令:jmap -dump:format=b,file={path} {pid}

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

dump 檔案路徑:D:\heapdump_108244.hprof

3、利用MAT分析 dump 檔案

MAT:Memory Analyzer Tool,是針對 java 的記憶體分析工具;下載地址:

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

選擇對應的版本,下載後直接解壓;預設情況下,mat 最大記憶體是1024m,而我們的 dump 檔案往往大於 1024m,所以我們需要調整,在 mat 的 home 目錄下找到MemoryAnalyzer.ini,將-Xmx1024m修改成大於 dump 大小的空間, 我把它改成了-Xmx4096m

接著我們就可以將 dump 檔案匯入 mat 中,開始 dump 檔案的解析

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

解析是個比較漫長的過程,我們需要耐心等待

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

解析完成後,我們可以看到如下概況介面

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

各個視窗的各個細節就不做詳細介紹了,有興趣的可自行去查閱資料;我們來看看幾個圖:餅狀圖、直方圖、支配樹、可疑的記憶體洩露報告

餅狀圖

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

可以看出,com.lee.schedule.Schedule物件持有 1G 記憶體,肯定有問題

直方圖

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

我們看下 Person 定義

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

可想而知,上圖示記的幾項都與 Person 有關

支配樹

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

這就非常直觀了,Schedule 中的 ArrayList 佔了 99.04% 的大小

可疑的記憶體洩露報告

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

通過這些資料,相信大家也能找到問題所在了

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

Linux

排查方式與 Windows 一樣,只是有稍許的命令區別

1、找到記憶體佔有率最高的程序號

使用命令:top -c顯示執行中的程序列表資訊,shift + m按記憶體使用率進行排序

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

程序號:2527

2、利用jmap生成堆轉儲快照

命令:jmap -dump:format=b,file={path} {pid}

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

堆轉儲快照檔案路徑:/opt/heapdump_2527.hprof

3、利用MAT分析堆轉儲快照

將heapdump_2448.phrof下載到本地,利用MAT進行分析;分析過程與 Windows 版完全一致

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

自此,定位到問題

Windows下 與 Linux 下,排查流程是一樣的

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

總結

JVM 常用命令

jps:列出正在執行的虛擬機器程序

jstat:監視虛擬機器各種執行狀態資訊,可以顯示虛擬機器程序中的類裝載、記憶體、垃圾收集、JIT編譯等執行資料

jinfo:實時檢視和調整虛擬機器各項引數

jmap:生成堆轉儲快照,也可以查詢 finalize 執行佇列、Java 堆和永久代的詳細資訊

jstack:生成虛擬機器當前時刻的執行緒快照

jhat:虛擬機器堆轉儲快照分析工具

與 jmap 搭配使用,分析 jmap 生成的堆轉儲快照,與 MAT 的作用類似

排查步驟

1、先找到對應的程序:PID

2、生成執行緒快照stack(或堆轉儲快照:hprof)

3、分析快照(或堆轉儲快照),定位問題

記憶體洩露、記憶體溢位和 CPU 100% 關係

JVM常見線上問題 → CPU 100%、記憶體洩露 問題排查

常用 JVM 效能檢測工具

Eclipse Memory Analyer、JProfile、JProbe Profiler、JVisualVM、JConsole、Plumbr

入手學習【覆盤】(視訊教程+面試寶典+pdf書籍+筆記+學習思維導圖 )

Java進階架構師視訊教程:價值上萬足足100G、1000+小時架構師教程.,Java程式設計師進階架構師看這個就夠了!

程式設計師必備演算法教程:有史以來最全阿里、騰訊、位元組、美團、谷歌演算法面試題合集

Java面試教程合集:2020年覆盤阿里、位元組、美團、騰訊、谷歌Java面試(大廠必問108個知識點)