2021-06-21

@[TOC]JAVA内存溢出分析

在线上运行过程中,突然出现反复宕机问题分析处理过程

  • 观察程序运行监控历史曲线,发现Old Gen曲线一直居高不下,并且cpu是用率飙升。分析得出结论:应该是内存溢出导致java虚拟机频繁进行GC,从而导致cpu升高。
    在这里插入图片描述
  • 启动脚本中加入-XX:+HeapDumpOnOutOfMemoryError参数,在内存溢出时会产生一个hprof后缀的DUMP文件。
    在这里插入图片描述
  • 使用IBM HeapAnalyzer加载DUMP文件进行分析,发现是一个SfcData创建了几万个对象导致,但是没法定位具体调用位置。
    在这里插入图片描述
  • 为进一步确认具体位置,将jstack编写成脚本,在程序出现异常时运行。
    在这里插入图片描述
    下面展示一些 内联代码片
#######################pid关键字为biz的java进程中cpu>0的线程的堆栈######
pid=`ps -ef|grep biz.jar|grep -v 'grep'|awk '{print $2}'`
sfile="/opt/java.$pid.trace"
tfile="/opt/java.$pid.trace.tmp"
rm -f $sfile  $tfile
echo "pid $pid"

jstack $pid > $tfile
ps -mp $pid -o THREAD,tid,time|awk '{if ($2>0 && $8 != "-") print $8,$2}'|while read line;
do
        nid=$(echo "$line"|awk '{printf("0x%x",$1)}')
        cpu=$(echo "$line"|awk '{print $2}')
        echo "nid: $nid, cpu: $cpu %">>$sfile
        lines=`grep $nid -A 100 $tfile |grep -n '^$'|head -1|awk -F':' '{print $1}'`
        ((lines=$lines-1))
        if [ "$lines" = "-1" ];
        then
             grep $nid -A 100 $tfile  >>$sfile
             echo '' >>$sfile
        else
             grep $nid -A $lines $tfile  >>$sfile
        fi
done
rm -f $tfile
echo "read msg in $sfile"
###########  end  ############
  • 运行脚本,输出.trace文件,通过文件分析发现addSfcData方法占用cpu相对较高,定位程序位置,最终发现原因是程序中使用Mybatis-plus的selectOne方法,对象传参的时候关键栏位为空值,导致该栏位不作为查询条件加载了过多数据导致
    在这里插入图片描述
    在这里插入图片描述
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值