1. 程式人生 > >利用jvisualvm工具查找tomcat假死問題

利用jvisualvm工具查找tomcat假死問題

jvm內存快照分析 java垃圾不回收 tomcat假死原因查找 內存泄漏問題分析 java內存瞬間爆滿分析

解決由於jvm內存泄漏導致的頻繁fullgc帶來的tomcat假死問題分析

問題現狀:系統運行期間突然出現tomcat假死,因為系統很久沒改代碼,以為是訪問量增加帶來的內存導致,改大內存後觀察,用jstat觀察系統平穩運行,old區穩定增長。

問題分析:
技術分享圖片

於是寫個腳本監控,內存是否還會暴漲,順便重啟下系統預防tomcat假死
#!/bin/bash
export JAVA_HOME=/u01/install/java
export CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$JAVA_HOME/bin:$PATH

pid=ps -aux| grep "java" | grep "tomcat-stweb-web" | awk ‘{print $2}‘

;
old=/u01/install/java/bin/jstat -gcutil $pid | awk ‘NR==2{print $4}‘ ;
old=${old//./ };
arr=($old); echo ${arr[0]} ;
if [ ${arr[0]} -gt 60 ] ;
then
/usr/bin/kill -9 $pid ;
/u01/install/tomcats/tomcat-stweb-web/bin/startup.sh ;
fi

一段時間之後,還是發現tomcat重啟了,也就是說不是內存不夠的問題,於是只能dump出內存暴漲時的內存快照,在上面代碼中加入
/u01/install/java/bin/jmap -dump:live,format=b,file=/u01/install/${pid}.hprof $pid ;在tomcat重啟之前dump出當時的內存快照文件到本地,使用jvisualvm分析,註意分析內存快找電腦必須夠強悍,至少16G內存要不很難轉儲內存快照文件。

啟動jvisualvm 導入快照文件

技術分享圖片

查看內存中但是哪些類的對象數最多,此時對象數一般就是引起內存暴漲的根本原因,要麽是程序bug導致的內存泄漏,要麽就是對象來不及回收

技術分享圖片

上圖中SimpleProdStat 和 Image 對象是自定義對象裏面最多的,應該是異常(如果分析這個到底是不是bug,可以在程序內存沒有暴漲正常情況下dump出快照分析看看有無此對象,如果有此對象但是個數保持穩定個數也正常,要是異常暴增應該考慮是是內存沒回收導致)

繼續查看該對象內存回收的根入下圖:

技術分享圖片

技術分享圖片

如上圖該個數最多的對象,垃圾回收的根節點為下圖:

技術分享圖片

技術分享圖片

回收的根結點為ArrayList,下面看看這個ArrayList在在哪裏被調用可以查看該對象的線程調用棧

技術分享圖片

技術分享圖片

在上圖標紅的框就是剛才ArrayList內存在線程中調用,繼續往下看,找到最終調用的業務方法

技術分享圖片

問題解決:

上圖標紅的地方為業務調用處,打開eclipse,發現這裏一次從數據庫查詢一個用戶的simpleprodstat對象,很多都為幾萬幾千個對象一次查詢到賬jvm內存瞬間爆滿而帶來的fullgc導致的tomcat假死,修改業務改成分頁查詢就可以解決問題。

利用jvisualvm工具查找tomcat假死問題