Java程序CPU高占用问题实战分享
作为服务器算力的核心部件CPU来说,异常高的占用会影响服务的正常运行。某个Java应用占用过高CPU,如果不是程序过于复杂需要优化,则可能是程序逻辑有问题,那么如何根据CPU高占用的现象排查程序问题,接下来通过实际案例来演示。

排查过程
案例一
- 使用top命令定位CPU高占用Java进程PID。
- 再使用top -Hp 4315查看该进程下各个线程的CPU使用情况,4315是步骤1中高CPU占用的进程号PID,可观察到前10个线程的CPU占用异常高。
- 选取步骤2中的一个线程进行分析,需要对其线程号进行进制转换,方便下一步查找。
- 使用jstack查询具体线程状态。Jstack 4315 | grep 0x10fd-A30可查看线程状态查找关键字向下30行内容,可看到线程状态为RUNNABLE,根据下列内容定位到代码ThreadTestWhile.java第15行。
- 查看代码逻辑,第15行为死循环,就是它导致了线程一直在运行,占用了过高CPU资源,修改该死循环即可解决问题。
案例二
- 另外一种情况是可能线程占用资源不是很多,但线程数量过多,海量线程数累计占用了过多资源导致CPU过高,同样使用top命令定位问题进程。
- 再通过top -Hp 11159查看到异常线程。
- 选取11183线程进行进制转换。
- 使用jstack 11159 | grep 0x2baf-A30查看到该线程状态为WATTING,过多的等待状态线程可能是代码中锁了资源导致线程一直处于等待状态。
- 本案例代码中是使用了suspend()方法挂起线程,又没有恢复导致的多线程等待,在程序设计时需要注意避免死锁的产生。
总结
1.使用top -Hp定位进程中占用CPU最高的线程,并结合jstack获取线程快照进行分析,如果线程是VMThread,则应该监控检查垃圾回收活动频率,看是否是因为频繁进行垃圾回收导致的。
2.Java高占用CPU通常原因都是出现了死循环,通过如上方法可以轻易定位到问题,另外空循环会导致间歇性CPU过高,案例一中top的CPU高占用就呈现出间歇性特点。
3.代码逻辑处理不当可能会导致堆内存无法及时回收导致内存泄漏引起CPU飙升,可结合内存进行问题定位。
本文作者:小本本(IT那活儿)
原创文章,作者:小编小本本,如若转载,请注明出处:https://www.benjiyun.com/yunzhujiyunwei/vps-yunwei/6503.html
