一次Java內存泄露處理手記

現象

最近項目組從NET平臺遷移到Java的Dubbo平臺上,因爲你們都是Java的生手,發生了蠻多的問題,之後一一記錄。如今解決一個遇到的關於Java程序內存泄露的問題。php

特別說明

Java萌新,理解不到位的地方請指點一二java

版本

  • Java 1.8
  • Dubbo 2.6.2
  • Docker 18.0.2

系統環境

咱們這裏是Docker Swarm集羣,三臺機器組成,Dubbo服務隨機部署到三臺機器上。docker

問題重現

上線了一個Dubbo服務,這個服務涉及到數據庫查詢、排序分析、第三方接口調用。
服務啓動初始內存佔用500MB左右,每檢索一次,內存增長10MB到幾十MB不等,並且不釋放。持續增高,最高能夠塞滿整個服務器的內存。shell

檢查問題

首先,因爲咱們是部署在Docker集羣上的,因此得去容器內進行檢查,剛上線,因此基礎容器選擇的是JDK版本,沒有用JRE。由於JDK帶有不少的調試工具。數據庫

查看生產環境並導出heap.hprof

首先看看容器的運行狀況:bash

docker stats

這是後面調試的時候截的圖,早期發現的時候,內存是4.8G。明顯內存佔用過多了。服務器

由於宿主是沒有任何java環境的,進容器內作內存分析。app

docker exec -it 容器ID bash # 進入指定容器
jmap -histo 1 | head -n 30 # 經過jmap工具查看

jmap的檢查結果當時忘了截圖了,這裏就不留存了,百度能搜到了,就一筆帶過。eclipse

如今導出heap.hprof文件,方便用MAT進行分析。工具

jmap -dump:format=b,file=heap.hprof 1

在docker容器內,PID 1 是服務進程,以上命令將會在當前目錄生成heap.hprof文件,比較大,個人有1.2G。能夠先壓縮了,再傳回來,進行分析。

使用MAT進行內存分析

獨立版下載地址:MAT

打開從服務器下載回來的heap.hprof文件

點擊Leak Suspects查看分析結果。

點擊Details查看詳情

上圖能夠看到,MAT分析結果代表,OcMapperFactory這個類有問題。

看看具體代碼:

這個OcMapperFactory是用來封裝orika的工具類,而orika是一個對象映射工具。因爲這裏沒有用單例致使了內存的泄露。加上單例再看看:

從新測試,發現內存已經穩定。

相關文章
相關標籤/搜索