一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原因都是出现了死循环。
(友情提示:本博文章欢迎转载,但请注明出处:hankchen,http://www.blogjava.net/hankchen)
以我们最近出现的一个实际故障为例,介绍怎么定位和解决这类问题。
根据top命令,发现PID为28555的Java进程占用CPU高达200%,出现故障。
通过ps aux | grep PID命令,可以进一步确定是tomcat进程出现了问题。但是,怎么定位到具体线程或者代码呢?
首先显示线程列表:
ps -mp pid -o THREAD,tid,time
找到了耗时最高的线程28802,占用CPU时间快两个小时了!
其次将需要的线程ID转换为16进制格式:
printf "%x\n" tid
最后打印线程的堆栈信息:
jstack pid |grep tid -A 30
找到出现问题的代码了!
现在来分析下具体的代码: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命令。可以查看某个进程的当前线程栈运行情况。
(友情提示:本博文章欢迎转载,但请注明出处:hankchen,http://www.blogjava.net/hankchen)
相关推荐
CPU过高通常与过度的计算、无尽循环、死锁、线程竞争状态等问题相关。在Java编程中,WeakHashMap是一种特殊的哈希表,它的键(Key)是弱引用,当键被垃圾回收器清除后,即使有值(Value)存在,该条目也会自动从哈希...
MySQL占用CPU过高的解决方案 在这篇文章中,我们讨论了MySQL占用CPU过高的问题及其解决方案。该问题可能会导致服务器性能下降,影响用户体验。通过实践案例,我们将展示如何诊断和解决该问题。 一、问题描述 ...
标题“解决Dreamweaver CS6占用CPU过高”指的是在使用Adobe Dreamweaver CS6这款流行的网页设计和开发工具时,可能会遇到程序运行过程中CPU使用率异常高的问题。这可能导致计算机性能下降,影响工作效率。以下是一些...
SQL 语句导致 Oninit 进程占用 CPU 过高问题定位方法 在本篇文章中,我们将探讨如何定位导致 Oninit 进程占用 CPU 过高的问题,并找到引起该问题的根源 SQL 语句。以下是问题描述、分析和解决方法。 问题描述 在 ...
"svchost引起的cpu过高解决方案" 在计算机系统中,CPU 使用率是一个非常重要的指标,它直接关系到计算机的性能和响应速度。高CPU 使用率可能会导致计算机运行缓慢、响应迟钝、系统崩溃等问题。今天,我们将讨论 ...
【CPU占用率过高】是许多计算机用户经常遇到的问题,尤其在使用IDE(集成开发环境)如Idea时,CPU资源的消耗可能导致系统运行缓慢甚至变得不可用。以下是一些可能导致CPU占用率过高的原因及其解决方案: 1. **防...
### CPU占用过高解决办法 在日常使用电脑的过程中,我们可能会遇到CPU占用率突然飙升至100%的情况,这种情况不仅会导致电脑运行缓慢,甚至可能使系统卡顿或死机。以下是一些有效的解决方法,帮助您缓解CPU占用过高...
wsappx占cpu过高怎么办?
AI导致CPU占用过高.rar 具体可以参考: https://geo-ai.blog.csdn.net/article/details/124564268?spm=1001.2014.3001.5502
将定位cpu过高的命令做了一个整理,直接执行脚本定位问题
如果以上操作完成后,还是无法解决 CPU 占用率过高的问题,就需要将防病毒软件病毒定义升级至最新版本,对全盘进行扫描查杀是否存在病毒。对于顽固的病毒,需要将该终端离线,在安全模式下进行彻底查杀。 Symantec...
服务器程序有时候不知道是什么原因导致CPU异常变高,每次变高都需要手工重启程序或服务,很麻烦,于是我就写了这个程序分享给网友朋友,希望能够帮到大家。使用说明,可自定义CPU负载多少,持续多少秒,执行相关bat...
在Java应用开发中,CPU过高通常是一个棘手的问题,它可能导致服务器性能急剧下降,甚至影响整个系统的稳定性。本文将深入探讨一次由于Java应用导致CPU占用过高的排查实践过程。 首先,当发现应用CPU使用率异常时,...
【Foobar2000 CPU占用率居高不下】的问题可能是由于软件内部处理音频时的资源管理不当导致的。Foobar2000是一款高级的音频播放器,它支持多种音频格式和插件,但有时可能会因为开启过多的DSP模块或不恰当的输出设置...
VMware虚拟机NAT CPU使用率高解决办法
本篇文章将探讨一个常见的问题——"线上应用故障排查之一:高CPU占用"。高CPU占用可能导致系统响应变慢,影响用户体验,甚至可能导致服务崩溃。解决这个问题需要深入理解应用程序的运行机制以及系统资源的管理。 ...
1.前言 CPU占用过高是LINUX服务器出现常见的一种故障,也是程序员线上排查错误必须掌握的技能,我们... 编写测试类,模拟占用CPU过高的程序,具体程序代码如下: public class TopTest { public static void main