JAVA处理 M_一次Java内存泄露处理手记
現(xiàn)象
最近項目組從NET平臺遷移到Java的Dubbo平臺上,由于大家都是Java的生手,發(fā)生了蠻多的問題,以后一一記錄。現(xiàn)在解決一個遇到的關(guān)于Java程序內(nèi)存泄露的問題。
特別說明
Java萌新,理解不到位的地方請指點一二
版本
Java 1.8
Dubbo 2.6.2
Docker 18.0.2
系統(tǒng)環(huán)境
我們這里是Docker Swarm集群,三臺機(jī)器組成,Dubbo服務(wù)隨機(jī)部署到三臺機(jī)器上。
問題重現(xiàn)
上線了一個Dubbo服務(wù),這個服務(wù)涉及到數(shù)據(jù)庫查詢、排序分析、第三方接口調(diào)用。 服務(wù)啟動初始內(nèi)存占用500MB左右,每檢索一次,內(nèi)存增加10MB到幾十MB不等,而且不釋放。持續(xù)增高,最高可以塞滿整個服務(wù)器的內(nèi)存。
檢查問題
首先,由于我們是部署在Docker集群上的,所以得去容器內(nèi)進(jìn)行檢查,剛上線,所以基礎(chǔ)容器選擇的是JDK版本,沒有用JRE。因為JDK帶有很多的調(diào)試工具。
查看生產(chǎn)環(huán)境并導(dǎo)出heap.hprof
首先看看容器的運(yùn)行情況:
docker stats
這是后面調(diào)試的時候截的圖,早期發(fā)現(xiàn)的時候,內(nèi)存是4.8G。明顯內(nèi)存占用過多了。
因為宿主是沒有任何java環(huán)境的,進(jìn)容器內(nèi)做內(nèi)存分析。
docker exec -it 容器ID bash # 進(jìn)入指定容器
jmap -histo 1 | head -n 30 # 通過jmap工具查看
jmap的檢查結(jié)果當(dāng)時忘了截圖了,這里就不留存了,百度能搜到了,就一筆帶過。
現(xiàn)在導(dǎo)出heap.hprof文件,方便用MAT進(jìn)行分析。
jmap -dump:format=b,file=heap.hprof 1
在docker容器內(nèi),PID 1 是服務(wù)進(jìn)程,以上命令將會在當(dāng)前目錄生成heap.hprof文件,比較大,我的有1.2G。可以先壓縮了,再傳回來,進(jìn)行分析。
使用MAT進(jìn)行內(nèi)存分析
獨(dú)立版下載地址:MAT
打開從服務(wù)器下載回來的heap.hprof文件
點擊Leak Suspects查看分析結(jié)果。
點擊Details查看詳情
上圖可以看到,MAT分析結(jié)果表明,OcMapperFactory這個類有問題。
看看具體代碼:
這個OcMapperFactory是用來封裝orika的工具類,而orika是一個對象映射工具。由于這里沒有用單例導(dǎo)致了內(nèi)存的泄露。加上單例再看看:
重新測試,發(fā)現(xiàn)內(nèi)存已經(jīng)穩(wěn)定。
總結(jié)
以上是生活随笔為你收集整理的JAVA处理 M_一次Java内存泄露处理手记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 过滤攻击报文_Spring B
- 下一篇: 宁波php吧,2020年9月程序员工资统