一个应用占用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使用情况。属于当前状态的采样数据。
也可以使用 top -p javaPid查看java纯程使用情况。
3、jstack:Java提供的命令。可以查看某个进程的当前线程栈运行情况。根据这个命令的输出可以定位某个进程的所有线程的当前运行状态、运行代码,以及是否死锁等等。
也可以使用 kill -3 javaPid将java纯程打印到控制台。
4、pstack:Linux命令。可以查看某个进程的当前线程栈运行情况。
相关推荐
### Java进程高CPU占用故障排查 在日常的运维与开发工作中,经常遇到Java应用出现高CPU占用的问题。这类问题不仅会影响系统的稳定性和响应速度,还可能导致服务不可用。因此,对于此类故障的快速定位和解决变得尤为...
在Java编程环境中,获取CPU占用率是常见的系统监控任务,这对于性能分析、故障排查或资源管理至关重要。要实现这一功能,通常需要利用Java提供的操作系统接口,例如Java Management Extensions (JMX) 或者 sun.misc...
系统异常通常指的是CPU占用率过高、磁盘使用率100%、系统可用内存低等情况;而业务异常则可能包括服务运行一段时间自动退出、服务间调用时间过长、多线程并发异常、死锁等问题。在进行故障排查时,第一步便是问题的...
### Java线上故障排查方案 #### 一、引言 在软件开发领域,处理生产环境中的问题是一项必备技能。生产环境中可能会遇到多种复杂的情况,比如代码bug、硬件故障、网络问题等,这些都可能导致应用程序无法正常运行。...
Java线上故障排查是每个Java开发者或运维人员必备的技能之一,尤其在生产环境中,快速定位并解决问题至关重要。本文将深入探讨Java线上故障排查方案,帮助你掌握一系列实用的方法和技术。 一、日志分析 1. 日志级别...
本文主要探讨了如何排查和解决Linux系统中CPU利用率高的问题,包括两种常用的方法以及一个实际的故障排查案例。 方法一: 1. 使用`top`命令,按下`Shift+p`对进程按CPU使用率进行排序,找到占用CPU最多的进程的PID...
在Java开发过程中,有时候我们需要监控系统资源或特定进程的状态,例如CPU使用率、内存占用情况等。这在服务器性能监控、问题排查等方面尤为重要。本文将详细介绍如何使用Sigar库来实现这些功能。 #### Sigar简介 ...
- 故障排查:通过观察CPU利用率的变化,可以帮助定位性能问题的源头,比如某个进程异常消耗资源。 总之,动态显示CPU利用率是一个强大的工具,它能够帮助我们实时了解系统的运行状态,及时发现并解决问题,提高系统...
1. **日志分析**:Java应用程序通常会产生大量的日志信息,这些日志是故障排查的第一手资料。通过分析日志,我们可以了解程序运行的状态、错误信息以及异常发生的时间点。关键的日志级别包括DEBUG、INFO、WARN、...
可以使用`ps`找到目标进程的PID,然后使用`top -H -p pid`找出CPU占用高的线程。将PID转换为16进制后,通过`jstack pid | grep 'nid' -C5 --color`查看堆栈详情。重点关注`WAITING`和`TIMED_WAITING`状态的线程,...
`show-busy-java-threads.sh` 文件提供了一个实用的脚本,帮助我们查看那些导致Linux系统CPU占用率升高的Java线程。 首先,让我们了解什么是JVM。JVM(Java Virtual Machine)是Java程序的运行环境,它负责解释和...
【描述】:本文将深入探讨当Websphere Application Server (WAS)出现异常高的CPU占用率时,如何识别问题源头并采取相应的故障排除措施。这涉及到对操作系统层面的数据收集、线程分析以及使用调试工具如dbx进行详细...
《实战JAVA虚拟机 JVM故障诊断与性能优化》这本书主要涵盖了Java开发者在实际工作中可能遇到的JVM相关问题,包括但不限于故障排查、性能调优、内存管理、垃圾收集机制等内容。以下将详细介绍这些知识点: 1. **Java...
总的来说,ProcExp 是一个强大的系统诊断工具,它提供的线程级监控功能在日常的系统管理和故障排查中起着关键作用。无论是开发者还是系统管理员,都应该掌握如何有效利用ProcExp来提升工作效率和系统稳定性。通过...
【计算机网络故障排查—经典】 在计算机网络使用过程中,我们可能会遇到各种问题,例如能上QQ但不能上网的情况。这通常是由多种因素引起的,本文将分析并提供解决这些问题的策略。 **一、病毒感染** 当打开IE浏览...
Arthas的灵活性和强大功能使其成为Java开发者必备的工具之一,它能有效提升问题排查的效率,确保应用程序的稳定运行。通过熟练掌握Arthas,开发者可以在面对复杂问题时更加从容,及时解决线上故障,保障服务的高可用...
通过阅读《实战Java虚拟机——JVM故障诊断与性能优化》,读者可以系统地学习JVM相关知识,提升故障排查和性能调优的能力。配合提供的源码和在线资源,读者可以在实践中加深理解和应用,使自己的Java开发技能更上一层...
Java IBM WebSphere应用服务器在运行过程中可能会遇到各种性能问题,其中最常见的挑战之一是内存溢出。内存溢出是指应用程序消耗的内存超过了系统所能提供的限制,导致程序崩溃或性能急剧下降。在这种情况下,开发者...
内存分析是软件开发过程中的重要环节,特别是在性能优化和故障排查时显得尤为关键。"Memory Analyzer"是一款专门针对Java应用程序的内存分析工具,它能够帮助开发者深入理解内存使用情况,定位内存泄漏问题,从而...