[TOC]
今天線上生產環境遇到一個內存溢出導致,內存被用完,導致db連接池爆掉的情況,下面我們主要來複盤一下故障的流程。
案例介紹
首先我們監控到我們的一個核心模塊最近一個月的gc 情況(最近一個月都沒有重啓服務,或者模塊升級)
(圖:06-01.jpg)
看到上圖,明顯發現每次fullgc 都沒有把內存給收回來的情況,存在着明顯的內存泄漏的問題。
(圖:06-02.jpg)
如圖06-02 這樣規律的波形圖纔是正常的gc 回收內存的過程,很明顯的是在週期內發生gc 內存都能被正常回收了。
案例分析
首先我們把該機器上jmap 一下把堆信息dump 下來。 我們的到 M1-001_jmap_700.hprof 文件。
對於堆文件的分析,這裏推薦mat(https://www.eclipse.org/mat/) 和 jprofiler 來進行分析。
在MemoryAnalyzer.ini
中增加或編輯以下值,防止Java heap space:
-vmargs
-Xmx2g
-XX:-UseGCOverheadLimit
jprofiler 分析
步驟1:打開.hprof 文件
2:雙擊第一個大對像
看到這個一直被引用的對象,然後翻看代碼
是某個打印日誌的組件在打印日誌後,沒執行pop,才導致這個一直套娃的鏈表大對像。
java dump
java dump 主要分2種,一個是內存dump,一個是線程dump 。
內存dump 可以執行 jmap 如:
jmap -dump:live,format=b,file=xxxheap-jmap.hprof 【pid】
線程dump 可以執行 jstack
jstack -l 【pid】 > 1.txt