發現問題
公司自己維護的服務三四個,有的服務還分多個節點,自己也有幾個私人服務器,所以爲了能實時知道各個服務器的情況,就使用ServerStatus做了個雲探針,功能很簡單,能實時的監控每個服務器的內存、cpu、硬盤、流量的使用情況,如下
雖然只有幾個指標,但是已經能讓我全面的掌握各服務的性能,再搭配chrome插件iChrome,每天打開瀏覽器就能第一時間看到監控界面,
我始終相信一句話:
工慾善其事必先利其器
最近一段時間,我發現我的一個服務所在的兩臺服務器內存處於不停的增長狀態,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
(最好要大於你的堆轉儲文件)
點擊“Leak Suspects”一般會顯示MAT它自己認爲有問題的內容,如下
同時會在堆轉儲文件的同級目錄下生成一個壓縮文件filename_Leak_Suspects.zip,裏面是一個html靜態頁面,我們也可以在瀏覽器去分析
點擊“Accumulated Objects in Dominator Tree”
就可以看到問題所在了
發現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,整個過程很順暢,當然了還需要對自己代碼非常熟才行,否則半天都不會定位到問題。
今天是七夕,祝各位程序員早早下班,陪女友吃好喝好玩好爲愛鼓掌到天明~~~~