您的位置:首页 > 其它

记一次OOM堆栈信息泄漏分析过程

2017-07-11 13:50 211 查看
1、用户反映生产订单下不来,马上打开服务器查看gc日志(前提是已经先排除了业务逻辑问题)

tomcat配置:

JAVA_OPTS=”$JAVA_OPTS -server -Xms4096m -Xmx4096m -Xss1024k -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+PrintGCDetails -Xloggc:/usr/local/gc.log -XX:+PrintGCTimeStamps”

查看gc日志:

tail -f gc.log



发现gc日志一直在作fullGc,频率在1分钟内,GC时间长达9秒,而且fullGC并没有释放出内存,因此断定服务器出问题了,查看了CPU,内存的使用率,

top -H -p pid

也发现CPU高达300%,平常是60%

为了恢复生产,此时服务器必须马上重启,但是为了查找出原因,先把堆栈信息打出来才能方便后续查找原因,保护现场很重要:

第一步:栈信息

jstack pid > jst.txt

第二步:堆信息

jmap -dump:format=b,file=jdump.bin pid

-dump: 生成Java堆转储快照

-heap:显示Java堆详细信息

-histo:显示堆中对象统计信息

然后恢复生产环境,重启,因为以前也是发生过一次这种情况,说明导致服务器挂掉的原因发生概率较小,是偶然性因素

2、分析堆栈信息:Memory Analyzer tools:AMT

分析工具采用AMT,可以在Eclipse安装也可以独立安装,打开工具,默认生成Leak Suspect report,内存泄漏报告



首先:overview,看到的是内存占用较大的对象

然后查看是由哪个线程产生的对象



点击 See stacktrace,可以看见栈信息



此时可以看到自己写的代码部分

最后点击details,查看这个GC不掉的内存对象是谁?



我们找到了线程,找到了内存对象,看来这个问题比较简单的被我们找到了问题症结点

3、回过去查找代码,此时我们至少能将问题锁定在某个具体的方法上,再去查找服务器生产业务日志,终于找到,原来是一个循环代码中,跳出条件有个隐蔽的边界条件,会导致死循环,生产服务器的日志也是一直在死循环,代码也能解释

OK,完成
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  oom-jmap oom