应用服务占用CPU过高情况排查

问题描述
(1)业务开发人员在启动项目时,会较高概率的出现cpu满载且一直无法停止的问题。任务管理器可以看到javaw.exe占用率为90%以上
(2)当启动项目时debug项目时,也会出现异常的卡顿,且能发现cpu占用率在稳步上升。
解决思路
1.尝试重现问题后,通过jvisualvm(jdk8中自带,后续版本被移除,但是可以兼容使用)工具观察堆、cpu运行的状态,能看出cpu是一直处于高负荷运行状态,且堆内存占用不大,GC线程也未占用cpu。可以判断是项目中部分线程一直在运行导致了cpu满载。
2.jps命令可以获取到当前运行的java进程号。通过比较cpu满载和jps列出的PID,可以确定满载的javaw.exe和Application为同一进程。


3.此时需要更进一步看到具体的线程占用情况,此时由于windows不能查看,需要下载对应的微软官方推荐的工具Process Explorer。

4.运行后选择对应的PID进程,右键点击选择Properties,可查看到对应的线程的TID。

5.在cpu发生满载现象时,执行命令jstack -l PID c:/*.stsck可获取到当前所有线程的状态。并在指定路径下生成了stack文件

6.此时获取到的TID为4位数字,通过win10自带的程序员计算器转换为16进制后在生成的stack文件中搜索线程即可。

7.此问题中定位到的线程如下,存在多个线程长期占用CPU且处于运行状态、

8.下面就是排查代码问题
发现当存在请求调用时,如果项目未启动则会导致此方法一直在自旋。
发生原因:


(1)由于liemsStarted变量未使用volatile关键字进行修饰,在多线程运行环境下,http线程并不能够及时的感知到此变量值已经改变。
(2)不加volatile会在编译时发生指令重排的优化,此代码可能会变成if(!liemsStarted){while(true){}}。
(3)while循环体中未执行任何代码,导致cpu无足够的间隔去重新获取liemsStarted的值,如果此处存在System.out.print,也可避免。
解决方案:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值