jar包运行一段时间后莫名其妙挂掉线上问题处理

本文讲述了如何通过top、free-m命令定位SpringBoot应用在Linux中的内存泄漏问题,通过jstack分析工具追踪到ServerHandler类的死循环源码,并给出了修复策略。涉及技术包括内存监控、线程分析和Java应用调试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、问题描述

springboot搭建的项目打包成jar包部署到Linux操作系统中,采用nohup java -jar 部署 jar 包后过一段时间(两三天)后莫名其妙挂掉(进程号PID被杀)。

2、问题定位

2.1 度娘一下

遇到这种问题,首先当然是去度娘找找看看有没有相似的人有这样的bug,看看别人的处理方法解决,结果当然是没找到合适的博客,所以就只能自己摸索摸索解决之道了。

2.2 基本操作

既然没有找到想要的,这种情况百分之九十九点九九九......的概率是内存泄露导致的。那基本操作来一下

2.2.1 top、free -m 指令

先用top指令看下Linux系统中的进程号使用情况

从上图可看到,cpu的占用竟然干到了 100.3%以上,这么耗费cup资源,肯定就是程序有问题了。

接着用 free -m查看下内存使用情况

 

结果发现这个空闲内存越来越少了,还真的是内存有问题。

3、问题深入定位

上面只是初步知道程序有问题,但是还是不知道具体的问题再哪里?就是这个问题在代码中哪里造成的还是不清楚

3.1 top -Hp PID 指令

输入PID指令将程序进程号的子线程使用系统资源的线程列举出来

从上图中可以看到733这个子线程占用了99.9%的cup使用率,这个线程肯定是有问题的,这个就要进入到JVM的栈中分析问题了,这里需要使用jstack工具进行分析问题。

3.2  jstack -l PID |grep -A 10 NID

因为在栈中的线程号是以16进制进行的,所以需要将上面733这个线程号转成16进制的数据,直接在Linux中转换: printf "%x\n"  733

然后采用jstack栈分析工具进行问题分析

jstack -l 655 |grep -A 10 0x2dd

这里的10是指打印10行的日志

找到这个子线程号,并且看到自己的报名和类,这个线程占用cpu 99.9%以上的资源就在类

ServerHandler的129行,赶紧去看看自己这个类的第129行到底写了什么东西。

这段代码直接导致了死循环,该段代码是希望读到输入流里面总的字节大小,但有时候因为网络原因无法一次读到结果,再加上while死循环,如果一直读不到,死循环就一直执行下去,故造成了死循环

4、解决

将上面导致死循环的代码注释掉改为缓存处理。

5、后续

以上是一次线程问题的解决,其实一次线上问题解决没有那么快就排查出来的,如果涉及到堆问题,需要将堆问题、栈日志打印保存下来分析

堆文件生成:jmap -dump:format=b,file=heap.hprof pid //保存了堆现场,b这里是字节的意思

(生成的堆文件采用mat分析软件定位问题)

栈日志生成:jstack pid > jstack.log //线程栈的现场

gc执行情况:jstat -gcutil 6343 5000  //每隔5秒检查gc使用情况

 

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值