标签: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假死,修改业务改成分页查询就可以解决问题。
标签:jvm内存快照分析 java垃圾不回收 tomcat假死原因查找 内存泄漏问题分析 java内存瞬间爆满分析
原文地址:http://blog.51cto.com/13703723/2103421