java CPU 100% 排查

本文介绍了一种定位并解决Java应用中高CPU占用问题的方法。通过使用top、ps、jstack等命令,成功定位到了问题代码,并给出了分析及解决思路。

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

一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原因都是出现了死循环。

(友情提示:本博文章欢迎转载,但请注明出处:hankchen,http://www.blogjava.net/hankchen

以我们最近出现的一个实际故障为例,介绍怎么定位和解决这类问题。

clip_image002

根据top命令,发现PID为28555的Java进程占用CPU高达200%,出现故障。

通过ps aux | grep PID命令,可以进一步确定是tomcat进程出现了问题。但是,怎么定位到具体线程或者代码呢?

首先显示线程列表:

ps -mp pid -o THREAD,tid,time

1

找到了耗时最高的线程28802,占用CPU时间快两个小时了!

其次将需要的线程ID转换为16进制格式:

printf “%x\n” tid

2

最后打印线程的堆栈信息:

jstack pid |grep tid -A 30

3

找到出现问题的代码了!

现在来分析下具体的代码:ShortSocketIO.readBytes(ShortSocketIO.java:106)

ShortSocketIO是应用封装的一个用短连接Socket通信的工具类。readBytes函数的代码如下:

public byte[] readBytes(int length) throws IOException {

    if ((this.socket == null) || (!this.socket.isConnected())) {

        throw new IOException(“++++ attempting to read from closed socket”);

    }

    byte[] result = null;

    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    if (this.recIndex >= length) {

           bos.write(this.recBuf, 0, length);

           byte[] newBuf = new byte[this.recBufSize];

           if (this.recIndex > length) {

               System.arraycopy(this.recBuf, length, newBuf, 0, this.recIndex - length);

           }

           this.recBuf = newBuf;

           this.recIndex -= length;

    } else {

           int totalread = length;

           if (this.recIndex > 0) {

                totalread -= this.recIndex;

                bos.write(this.recBuf, 0, this.recIndex);

                this.recBuf = new byte[this.recBufSize];

                this.recIndex = 0;

    }

    int readCount = 0;

    while (totalread > 0) {

         if ((readCount = this.in.read(this.recBuf)) > 0) {

                if (totalread > readCount) {

                      bos.write(this.recBuf, 0, readCount);

                      this.recBuf = new byte[this.recBufSize];

                      this.recIndex = 0;

               } else {

                     bos.write(this.recBuf, 0, totalread);

                     byte[] newBuf = new byte[this.recBufSize];

                     System.arraycopy(this.recBuf, totalread, newBuf, 0, readCount - totalread);

                     this.recBuf = newBuf;

                     this.recIndex = (readCount - totalread);

             }

             totalread -= readCount;

        }

   }

}

问题就出在标红的代码部分。如果this.in.read()返回的数据小于等于0时,循环就一直进行下去了。而这种情况在网络拥塞的时候是可能发生的。

至于具体怎么修改就看业务逻辑应该怎么对待这种特殊情况了。

 

最后,总结下排查CPU故障的方法和技巧有哪些:

1、top命令:Linux命令。可以查看实时的CPU使用情况。也可以查看最近一段时间的CPU使用情况。

2、PS命令:Linux命令。强大的进程状态监控命令。可以查看进程以及进程中线程的当前CPU使用情况。属于当前状态的采样数据。

3、jstack:Java提供的命令。可以查看某个进程的当前线程栈运行情况。根据这个命令的输出可以定位某个进程的所有线程的当前运行状态、运行代码,以及是否死锁等等。

4、pstack:Linux命令。可以查看某个进程的当前线程栈运行情况。

转载自:https://www.cnblogs.com/lishijia/p/5549980.html

<think>我们正在处理用户关于Linux虚拟机中CPU使用率达到100%的问题排查与解决方法。根据引用内容,我们可以总结出以下步骤: 1. 使用top命令查看整体CPU使用情况,并按下数字1查看每个CPU核心的使用率。 2. 在top的进程列表中,查看哪个进程的%CPU列显示过高,记录下进程ID(PID)。 3. 使用pidstat命令进一步分析该进程的CPU使用情况,包括用户态、内核态、等待等。 4. 根据进程ID,可以结合其他命令(如ps)或者查看日志,定位到具体的线程或代码段。 另外,引用[4]提到,在非高并发或CPU密集型应用中,突然的CPU使用率飙升很可能是业务代码逻辑问题。 因此,我们的回答应该包括以下步骤: 步骤1:使用top命令定位高CPU占用的进程。 步骤2:使用pidstat命令详细分析该进程的CPU使用情况。 步骤3:定位到具体线程(如果有必要,可以使用top -Hp PID或者pidstat -t -p PID)。 步骤4:结合进程/线程信息,使用jstack(如果是Java应用)或其他调试工具分析线程堆栈,找到问题代码。 注意:用户提到是虚拟机环境,所以引用中提到的%guest(运行虚拟机占用的CPU)也需要关注。 下面我们按照要求生成回答,并添加相关问题。</think>### Linux虚拟机CPU 100%使用率排查与解决方法 当Linux虚拟机出现CPU持续100%使用率时,可按以下步骤排查: #### 1. **定位高负载进程** - 运行 `top` 命令查看实时进程: ```bash top ``` - 按下数字 `1` 查看每个CPU核心的使用率[^1][^2] - 按 `P`(大写)按CPU使用率排序进程 - 记录高负载进程的PID(如Java应用常出现此问题[^3]) #### 2. **分析进程详情** 使用 `pidstat` 深入分析: ```bash pidstat -p [PID] 1 5 # 每1秒采样1次,共5次 ``` 输出指标解读: - `%usr`:用户态CPU使用率 - `%system`:内核态CPU使用率 - `%guest`:虚拟机占用CPU(虚拟化环境关键指标[^1]) - `%wait`:等待CPU时间 - `%CPU`:总使用率[^1][^2] #### 3. **线程级分析** 对高负载进程进行线程排查: ```bash top -Hp [PID] # 查看进程内线程 printf "%x\n" [TID] # 将线程ID转为16进制(用于堆栈分析) ``` #### 4. **检查系统日志** 查看内核和系统日志: ```bash dmesg | grep -i error # 内核错误 journalctl -b -p 3 # 本次启动的严重日志 ``` #### 5. **常见问题场景与解决** | 问题类型 | 排查命令 | 解决方案 | |-------------------|-----------------------------|----------------------------| | **Java应用异常** | `jstack [PID] > stack.log` | 分析线程堆栈,定位死循环/锁竞争[^3] | | **内核资源竞争** | `vmstat 1` | 优化虚拟机配置或宿主机资源分配 | | **僵尸进程** | `ps aux | grep 'Z'` | 终止父进程或重启服务 | | **配置错误** | `sysctl -a` | 调整虚拟机CPU配额或优先级 | #### 6. **持续监控工具** 安装基础监控组件: ```bash # Ubuntu/Debian apt install sysstat htop # CentOS/RHEL yum install sysstat htop ``` 使用 `sar -u 1 10` 查看历史CPU负载趋势 > **特别注意**:在虚拟化环境中,需同时检查宿主机资源分配。案例显示某平台服务器因非高并发应用突遇98.94% CPU使用率,最终定位为业务代码逻辑问题[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值