Java的CPU 飙升700%优化的真实案例

最近负责的一个项目上线,运行一段时间后发现对应的进程竟然占用了700%的CPU,导致公司的物理服务器都不堪重负,频繁宕机。

那么,针对这类java进程CPU飙升的问题,我们一般要怎么去定位解决呢?

采用top命令定位进程

登录服务器,执行top命令,查看CPU占用情况,找到进程的pid
在这里插入图片描述
很容易发现,PID为29706的java进程的CPU飙升到700%多,且一直降不下来,很显然出现了问题。
使用top -Hp命令定位线程
使用 top -Hp命令(为Java进程的id号)查看该Java进程内所有线程的资源占用情况(按shft+p按照cpu占用进行排序,按shift+m按照内存占用进行排序)

此处按照cpu排序:在这里插入图片描述
很容易发现,多个线程的CPU占用达到了90%多。我们挑选线程号为30309的线程继续分析。

使用jstack命令定位代码

1.线程号转换5为16进制

printf “%x\n” 命令(tid指线程的id号)将以上10进制的线程号转换为16进制:
在这里插入图片描述
转换后的结果分别为7665,由于导出的线程快照中线程的nid是16进制的,而16进制以0x开头,所以对应的16进制的线程号nid为0x7665

2.采用jstack命令导出线程快照

通过使用dk自带命令jstack获取该java进程的线程快照并输入到文件中:
在这里插入图片描述

3.根据线程号定位具体代码

在jstack_result.txt 文件中根据线程好nid搜索对应的线程描述
在这里插入图片描述
根据搜索结果,判断应该是ImageConverter.run()方法中的代码出现问题

当然,这里也可以直接采用
在这里插入图片描述

分析代码解决问题

下面是ImageConverter.run()方法中的部分核心代码。

逻辑说明:
在这里插入图片描述
在while循环中,不断读取堵塞队列dataQueue中的数据,如果数据为空,则执行continue进行下一次循环。

如果不为空,则通过poll()方法读取数据,做相关逻辑处理。

初看这段代码好像每什么问题,但是如果dataQueue对象长期为空的话,这里就会一直空循环,导致CPU飙升。

那么如果解决呢?

分析LinkedBlockingQueue阻塞队列的API发现:
在这里插入图片描述
这两种取值的API,显然take方法更时候这里的场景。

代码修改为:
在这里插入图片描述
重启项目后,测试发现项目运行稳定,对应项目进程的CPU消耗占比不到10%。
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java程序中,可能会出现CPU飙升的情况,导致CPU占用率异常高。这种情况通常是由于程序中存在某些问题导致的,以下是几个可能引起CPU飙升的原因和解决方法: 1. 无限循环:如果程序中存在无限循环或者循环次数过多的情况,会导致CPU不断处理循环,造成占用率飙升。解决方法是检查代码中的循环逻辑,确保循环条件正确,并添加合适的退出机制。 2. 频繁的IO操作:如果程序中存在大量的IO操作,特别是磁盘读写或网络通信,会消耗大量的CPU资源,导致占用率飙升。解决方法是对IO操作进行优化,如使用缓冲区、批量处理等方式减少IO次数。 3. 线程处理不当:如果程序中使用了大量的线程,而这些线程没有得到合理的调度和管理,会导致CPU负载过高。解决方法是检查线程逻辑,确保线程的启动和销毁得当,并考虑使用线程池等方式管理线程。 4. 死锁或竞态条件:如果程序中存在死锁或竞态条件,会导致多个线程互相等待对方释放资源,从而造成CPU飙升。解决方法是对代码进行仔细审查,确保没有死锁或竞态条件的存在。 5. 过度使用递归:如果程序中过度使用递归算法,会导致CPU进行大量的方法调用,从而造成占用率飙升。解决方法是使用迭代或其他非递归方式实现算法,避免过深的递归调用。 总之,当Java程序引起CPU飙升时,需要仔细检查代码逻辑,并对可能的问题进行排查和优化,以确保程序的性能和稳定性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值