java生产环境调优(3) 模拟一次CPU飙高,以及原因分析

本文通过模拟死循环场景,介绍如何使用top和jstack工具定位CPU飙高的原因,包括如何查看CPU使用率,分析线程堆栈,及确定死循环代码位置。

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

一般CPU的性能都是比较过剩的,随便打开一台电脑,他的内存可能会被撑爆,但是cpu撑爆就相对比较少见了,因为CPU够快啊
就拿i7 8750H举例,6核心12线程
默认频率2.2GHz, 单核turbo 4.1GHz,四核睿频4.0GHz,全核满载3.9GHz

这个数值很不错了,即使以最低的计算,2.2GHz意味每秒可以计算20亿次左右,这个数据太多了,所以cpu才会分时计算

在线上的环境中,一般cpu飙高极大的可能性是出现了死循环了.


今天我们就来模拟一次这样的情况,以及出现这样的情况了,我们又该如何来进行定位找到代码中出现死循环的地方

1.统一环境 springboot 2.1.3.RELEASE,开启web支持

2.新建一个控制层,添加如下代码

 @GetMapping("/letCpuBusy")
    public void letCpuBusy(){
        int i=0;
        while(true) {
            i++;
        }

    }

代码是非常的简单,就是不停的加数字.循环永远不会退出来,所以会一直让cpu在运转

3.ok,打包,上传到阿里云的机器,运行

访问3次上面的这个接口

curl 127.0.0.1:8080/letCpuBusy

在这里插入图片描述

ok了,

可是问题来了,我们运行了死循环的程序,可是我们表面上是看不出来的啊?

我们访问这个应用的其他的接口照样是可以访问的.

这个时候一个linux 的命令就派上用户了

top

top命令可以查看linux 主机的各种健康状态,当然也包含cpu 的

我们先执行一次top 看一下

在这里插入图片描述

注意看红框处,效果上来了 是不是?

我们跑了3个死循环,让这个java 的应用cpu利用率 飙到了99.7%

这个应用其实是不正常的了.正常情况下是不会这么高的.

ok 回到问题,由于这个是我们手动构建的,我们知道是什么原因导致的,在真实的环境中,怎么知道是哪里的代码出现了死循环么?

这个时候一个工具就登场了:jstack

4.jstack可以导出java进程的所有线程信息

先查看java应用的pid信息

jps -l

然后

jstack pid >123.txt

把这个文件下载到自己的电脑上,这个文件保存了java 应用的所有的线程信息

5.我们知道进程下面可以分为线程,刚才我们访问了3次死循环,所以,这个java 应用里面应该与3个死循环的线程
那么怎么办查看了?

top -p pid -H

在这里插入图片描述
正好是3个, 所以所以7122 7120 7121 这3个pid 就是对应的那3个死循环的线程id了

只不过这3个数字都是10进制的,需要转一下16进制
7122D-> 1bd2H
7120D-> 1bd0H
7121D-> 1bd1H

以第一个具体,打开刚才的那个123.txt文件

搜索1bd2在这里插入图片描述
jstack中已经把完整的调用堆栈都打印出来了

观察线程状态是RUNNABLE,正在运行中

第一行给了我们提示代码的位置

at com.example.demo.controller.UserController.letCpuBusy(UserController.java:61)

下面看下代码

在这里插入图片描述

正好就是61行

至此问题都已经定位到了


总结一下,一般按情况下cpu飙高还是比较少见的,因为cpu一直都是很强的,但是如果有一天在真实的环境中遇到这样的情况了,还是要有一定的思路去解决这样的问题,而不是惊慌失措不知道干怎么办.

相较于分析内存溢出的问题,cpu 的飙高分析要简单的多.也好定位和分析.

写这篇文章的时候恰好看到甲方的人在公司群讨论cpu飙高的问题

在这里插入图片描述

这个是mongo的程序的cpu飙高了,mongo作为一款广泛使用的数据库,他的cpu占用这么高,应该不太可能是mongo本身的原因,
就好比你用mysql数据库不停的执行select * from xxx 大表查询一样,问题还是出在开发本身,所以在开发过程中要注重下sql 或者 nosql 的查询执行的性能,当然这个是相当考验基本功的,必须要有长足的开发经验和实践.

学习之路还漫长,加油!

在这里插入图片描述

补充一下吧.上次在一次面试的过程中,2个面试官,其中一个人问我 jstack 怎么用,当然顺口就说出来了.

问了一会儿,另外一个人问我有没有遇到过死锁,遇到死锁该怎么解决?

我说没有,在平时哪会遇到死锁什么的.

这个时候面试官说,其实就是你刚才说的那个jstack可以定位

那个时候突然一想,对啊,死锁不就是cpu在等待么.jstack 不就是查看线程栈么.

所以要活学活用啊,仅仅是记住一些命令的功能,没有扩展,惭愧啊.

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值