记一次生产内存溢出

客户反馈服务无法登陆

1 查看服务器中服务进程存在

2 查看服务内存情况,内存已满,gc报错oom

3 查看服务获取服务堆栈信息,拉下来分析

4 jprofile内存分析

5 查看线程 ,服务信息找到一个后台查询接口,堆栈信息中大文件是数据库查询结果,查看接口,堆栈信息中数据与接口查询表字段对应。判断是接口中未设置limit条件,数据库表中数据100W+,全量查询导致

6 修改查询接口 以上

补偿具体过程:

1.进程存在,尝试手动打印进程堆栈信息,使用命令:

jmap -dump:format=b,file=heapdump.hprof pid

2.尝试查找线程工作线程堆栈: 

jstack -l 4089 >1.txt

3.问题分析

大多问题发现时,进程中的问题过程仍然在运行,所以看实时线程堆栈信息,一般能找到的服务相关内容,值得分析一下。

比如我这里的例子,线程堆栈中涉及项目的工作线程并不多,线程中也没有lock状态,这里就是查看线程信息中代码业务,结合生产日志分析业务影响。

还有一次遇到服务cpu100%,8核cpu,业务流量也不多没有高并发,通过线程堆栈,发现一个高频业务,占用几十个线程,查看业务代码发现业务中for循环查询操作。

这里贴一份之前查高频CPU线程的脚本:

#!/bin/bash

#Step1 打印占用CPU过高的进程ID
#top -b -d3 -n1 -u hotel | awk '/PID/,0' > ./_pid_out.out
#v_pid=`awk 'NR==2 {print $1}' ./_pid_out.out`
v_pid=$1 
echo $v_pid 
#Step2 打印进程中占用CPU过高的线程ID
top -b -d3 -n1 -H -p $v_pid | awk '/PID/,0' > ./_tid_out.out
v_tid=`awk 'NR==2 {print $1}' ./_tid_out.out`
 
 
#Step3 将线程ID转为16进制
#echo 'ibase=10;obase=16;$v_tid' | bc
v_tid16=`printf %x $v_tid`
echo "thread id[hexadecimal] is : 0x${v_tid16}"
echo ""
 
#Step4 打印CPU占用过高的进程的线程栈
echo "wait 5 seconds, please..."
jstack $v_pid > ./_thread_stack.out
sleep 5s
 
#Step5 在 _thread_stack.out 中查找线程执行的具体代码,打印改行及其之后30行,并高亮显示匹配内容
cat ./_thread_stack.out | grep -n --color=auto -A 30 -i 0x${v_tid16}
 
#clean
rm -rf ./_pid_out.out
rm -rf ./_tid_out.out
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值