一、開發環境:
linux 3.10.0-327.el7.x86_64
weblgoic:10.3.6
應用環境JDK版本:java version "1.6.0_45"
本地主機JDK版本:java version "1.8.0_211"
MAT版本:Eclipse Memory Analyzer Version 1.8.0
注:MAT1.8需要1.7及以上版本JDK。
二、內存泄漏分析過程以及代碼定位
1、通過主機內存監控,發現主機內存在不斷增加,重啓後依舊會出現同樣的問題。
2、查看JVM監控,發現Old Gen內存使用使用率在不斷上升,可以看到在GC時段存在內存回收,但是總體趨勢上升。
3、GC時間和次數也在不斷上升
出現這種情況,一般都是出現了內存泄漏,這種泄漏情況也是比較難判斷。
4、登錄主機,查看各存活類名、對象數量和對象佔用內存大小:
# jmap -histo:live 4762 | head -20
該com.xxxx.rmw.model.rmclass.pojo.ResClassIndexObj對象佔用內存如此多,很有可能與該代碼有關。
5、立馬做了一個線程Dump
# jmap -dump:format=b,file=476220190829.bin 4762
使用MAT工具打開獲得如下分析結果:
點擊"LeakSuspects".
此處給出了3個可疑問題。
com.xxxx.common.util.ResDelagateObj是開發商的代碼
點擊"Details >"
找到"Shortest Paths To the Accumulation Point"
藍色部分便是工具分析出來可能存在問題部分,點擊藍色部分,選擇Java Basics > Thread Details
這裏我們可以看到詳細的線程堆棧信息:
在之前的界面,點擊Java Basics > Thread Overview and Stacks
展開後,這裏我們可以看到問題對象有關的代碼調用。
記住這個
at com.xxxx.rga.querymaintain.services.QueryMaintainService.executeQueryByTransSql
接着回到線程堆棧中我們找到有關的代碼信息:
這裏引起內存泄漏的調用代碼。