一次排查Java項目內存泄漏的過程

發現問題

公司自己維護的服務三四個,有的服務還分多個節點,自己也有幾個私人服務器,所以爲了能實時知道各個服務器的情況,就使用ServerStatus做了個雲探針,功能很簡單,能實時的監控每個服務器的內存、cpu、硬盤、流量的使用情況,如下
實時監控圖
雖然只有幾個指標,但是已經能讓我全面的掌握各服務的性能,再搭配chrome插件iChrome,每天打開瀏覽器就能第一時間看到監控界面,
iChrome.png
我始終相信一句話:

工慾善其事必先利其器

最近一段時間,我發現我的一個服務所在的兩臺服務器內存處於不停的增長狀態,8g內存,直接超過65%,這讓我很鬱悶,爲什麼會醬紫,就在昨天,我在一個服務器上做測試(不是普通的測試,而是去驗證某正邏輯在線上是否正確的測試),然後整個服務直接宕機了,趕緊找公司的運維人員(你可能會問既然公司有運維,爲什麼還要自己搗鼓監控,我想說,作爲一個開發,最好能在第一時間發現任何問題,還有一句話“求人不如求幾”)看下服務器宕機前的狀態,果然是內存突然暴增,所以我就很有必要去找出導致服務內存持續增長原因。

jmap

網上找了一些命令,感覺jmap最好用

命令行輸入:jmap -histo <pid> | head -20,就可以查看某個pid的java服務佔用內存排名前20的類。注:該命令不適用於Windows系統裏

jmap -dump:format=b,file=filename.bin <pid>, 將整個內存情況保存到文件裏,然後導出使用MAT(Memory Analyse Tool)分析
注意:堆轉儲文件可能比較大,我的有2.5個G

MAT

Memory Analyse Tool 內存分析工具,直接下載,下載解壓之後,可以修改下配置文件MemoryAnalyzer.ini,修改裏面的參數如-Xmx5120m(最好要大於你的堆轉儲文件)

然後將堆轉儲文件導入進去就可以了
微信截圖_20180817134945.png

點擊“Leak Suspects”一般會顯示MAT它自己認爲有問題的內容,如下
微信截圖_20180817135050.png
同時會在堆轉儲文件的同級目錄下生成一個壓縮文件filename_Leak_Suspects.zip,裏面是一個html靜態頁面,我們也可以在瀏覽器去分析

點擊“Accumulated Objects in Dominator Tree”
就可以看到問題所在了
微信截圖_20180817135301.png
發現WordDictionary中HashMap的數量異常,然後一層一層的網上找,發現了這句代碼

public class xxx {
    private JiebaSegmenter segmenter = new JiebaSegmenter(); // 分詞
}

然而項目裏對這個xxx類依賴較多,每次使用xxx的時候,都要重新去創建JiebaSegmenter對象。。。。
趕緊將其改爲

    private static JiebaSegmenter segmenter = new JiebaSegmenter(); // 分詞

因爲這個分詞程序是直接在github上面找的代碼,所以沒有認真去看,真的是應了那句話“該來的遲早會來~~~”

最後

以上就是自己通過內存分析定爲到具體代碼的整個過程,之類MAT用的很簡單,只是簡單的分析,也可以參考這篇https://blog.csdn.net/wanghuiqi2008/article/details/50724676,整個過程很順暢,當然了還需要對自己代碼非常熟才行,否則半天都不會定位到問題。

今天是七夕,祝各位程序員早早下班,陪女友吃好喝好玩好爲愛鼓掌到天明~~~~

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