作者:青石路
鏈接:https://www.cnblogs.com/youzhibing/p/13599874.html
明明是個小 bug,但就是死活修不好,我特么心態(tài)崩了......
后文會從 Windows、Linux 兩個系統(tǒng)來做示例展示,有人會有疑問了:為什么要說 Windows
版的 ?目前市面上還是有很多 Windows 服務(wù)器的,應(yīng)用于傳統(tǒng)行業(yè)、政府結(jié)構(gòu)、醫(yī)療行業(yè) 等等;兩個系統(tǒng)下的情況都演示下,有備無患
后文中用到了兩個工具:Processor Explorer、MAT,它們是什么,有什么用,怎么用,本文不做介紹,不知道的小伙伴最好先去做下功課。
下面的示例中, cpu 的占有率沒到 100%,只是比較高,但是排查方式是一樣的,希望大家不要鉆牛角尖。
PID:20260
雙擊剛剛找到的 java 進程:
線程號:15900
,轉(zhuǎn)成十六進制:3e1c
jstack
生成虛擬機中所有線程的快照命令:jstack -l {pid} > {path}
文件路徑:D:\20260.stack
我們先瀏覽下快照內(nèi)容:
內(nèi)容還算比較簡潔,線程快照格式都是統(tǒng)一的,我們以一個線程快照簡單說明下:
"main" #1 prio=5 os_prio=0 tid=0x0000000002792800 nid=0x3e1c runnable [0x00000000025cf000]
我們前面找到占 cpu 最高的線程號:15900 ,十六進制:3e1c ,用 3e1c
去快照文件里面搜一下:
自此,找到問題。
排查方式與 Windows 版一樣,只是命令有些區(qū)別。
使用命令:top -c
顯示運行中的進程列表信息, shift + p
使列表按 cpu 使用率排序顯示:
PID = 2227
的進程,cpu 使用率最高。
使用命令:top -Hp {pid}
,同樣 shift + p
可按 cpu 使用率對線程列表進行排序:
PID = 2228
的線程消耗 cpu 最高,十進制的 2228
轉(zhuǎn)成十六進制 8b4
jstack
生成虛擬機中所有線程的快照分析方式與 Windows 版一致,我們可以把 2227.stack
下載到本地進行分析,也可直接在 Linux 上分析。
在 Linux 上分析,命令:cat 2227.stack |grep '8b4' -C 5
至此定位到問題。
不管是在 Windows 下,還是在 Linux 下,排查套路都是一樣的:
PID
第一眼看上去, idea
內(nèi)存占有率最高,因為我是以 idea 啟動的 java 進程;idea 進程我們無需關(guān)注,我們找到內(nèi)存占有率最高的 java 的 PID:10824
jmap
生成堆轉(zhuǎn)儲快照命令:jmap -dump:format=b,file={path} {pid}
dump 文件路徑:D:\heapdump_108244.hprof
MAT
分析 dump 文件MAT:Memory Analyzer Tool,是針對 java 的內(nèi)存分析工具;下載地址:
選擇對應(yīng)的版本,下載后直接解壓;默認(rèn)情況下,mat 最大內(nèi)存是 1024m
,而我們的 dump 文件往往大于 1024m,所以我們需要調(diào)整,在 mat 的 home 目錄下找到 MemoryAnalyzer.ini
,將 Xmx1024m
修改成大于 dump 大小的空間, 我把它改成了 Xmx4096m
接著我們就可以將 dump 文件導(dǎo)入 mat 中,開始 dump 文件的解析:
解析是個比較漫長的過程,我們需要耐心等待:
解析完成后,我們可以看到如下概況界面:
各個窗口的各個細(xì)節(jié)就不做詳細(xì)介紹了,有興趣的可自行去查閱資料;我們來看看幾個圖:餅狀圖、直方圖、支配樹、可疑的內(nèi)存泄露報告。
餅狀圖:
可以看出, com.lee.schedule.Schedule
對象持有 1G 內(nèi)存,肯定有問題。
直方圖:
我們看下 Person 定義:
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class Person {
private String name;
private Integer age;
}
可想而知,上圖標(biāo)記的幾項都與 Person 有關(guān)。
支配樹:
這就非常直觀了,Schedule 中的 ArrayList 占了 99.04% 的大小
可疑的內(nèi)存泄露報告:
通過這些數(shù)據(jù),相信大家也能找到問題所在了。
排查方式與 Windows 一樣,只是有稍許的命令區(qū)別
使用命令:top -c
顯示運行中的進程列表信息, shift + m
按內(nèi)存使用率進行排序
進程號:2527
jmap
生成堆轉(zhuǎn)儲快照命令:jmap -dump:format=b,file={path} {pid}
堆轉(zhuǎn)儲快照文件路徑:/opt/heapdump_2527.hprof
MAT
分析堆轉(zhuǎn)儲快照將 heapdump_2448.phrof
下載到本地,利用 MAT
進行分析;分析過程與 Windows 版完全一致
自此,定位到問題。
Windows 下與 Linux 下,排查流程是一樣的
jps
:列出正在運行的虛擬機進程jstat
:監(jiān)視虛擬機各種運行狀態(tài)信息,可以顯示虛擬機進程中的類裝載、內(nèi)存、垃圾收集、JIT編譯等運行數(shù)據(jù)jinfo
:實時查看和調(diào)整虛擬機各項參數(shù)jmap
:生成堆轉(zhuǎn)儲快照,也可以查詢 finalize 執(zhí)行隊列、Java 堆和永久代的詳細(xì)信息jstack
:生成虛擬機當(dāng)前時刻的線程快照jhat
:虛擬機堆轉(zhuǎn)儲快照分析工具:與 jmap 搭配使用,分析 jmap 生成的堆轉(zhuǎn)儲快照,與 MAT 的作用類似PID
stack
(或堆轉(zhuǎn)儲快照:hprof
)Eclipse Memory Analyer、JProfile、JProbe Profiler、JVisualVM、JConsole、Plumbr
-End-