只需4個步驟,分析解決在生產環境下JVM內存泄露問題

作者:未完成交響曲

發現異常

首先通過我們內部搭建的日誌平臺發現我們線上環境一個java應用有大量的http接口請求超時,登錄linux服務器查看網絡環境沒有問題,判斷是應用自身運行異常,重啓應用後發現異常還在,開始查找問題。

初步查找問題

通過指令:jstat -gcutil 查看jvm內存佔用和gc情況:

發現老年代內存佔用比例過高,並且每次fullGC後並沒有有效回收。老年代內存佔用百分比變化趨勢大致如下:

初步判斷大量請求超時和服務癱瘓的直接原因:

    每次fullGC後的內存佔用越來越高

    內存佔用增長速度越來越快

    fullGC的頻率越來越高

    最終佔用達到100%,服務完全癱瘓

分析處理

使用指令:jmap -histo:live *** | more 查看堆內存中的對象數量和大小

發現Log4jLogEvent這個對象實例很多,佔用內存也異常的大,初步分析是異步日誌傳輸速度跟不上,導致日誌對象堆積在內存中。

嘗試使用調整Flume傳輸日誌參數:提高flume單次傳輸量,減少最大延遲時間

重啓應用並監控接口調用情況發現應用暫時恢復正常了。

後續分析

在前一步分析內存的同時,使用指令:jmap -dump:format=b,file=heapDump.hprof將實時內存信息導出(dump過程比較慢,所以在問題暫時處理完後進行後續分析),使用mat分析內存結構:

可以看到主要佔據堆內存的對象信息,果然是Flume異步傳輸日誌堵塞的問題。

總結

對jvm內存泄露這類問題的解決,主要是要善於利用jvm提供的類似jstat、jmap等工具來分析查找問題。這次問題雖然解決,但是後續還是存在出現此類問題的風險。所以除了加強jvm問題排查能力的同時,我們也將建立應用監控平臺的計劃提上日程,希望能對jvm內存、線程等應用實時運行指標進行監控,便於儘早發現問題。

歡迎大家一起交流,喜歡文章記得關注我點個喜歡喲,感謝支持!

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