本文来说下JVM性能优化之CPU负载过高的问题
概述
一般性结论:一般来说,CPU占用高不高的问题,不是给定一个数值,例如90%以上就算高,以下就算正常,正常来说,随着程序的运行,CPU不断变化,百分之几,百分之几十,百分之百,都有可能,而CPU持续的高位,例如一直300%或者更多800%(多核),才可以认定为CPU占用过高问题。
对于java来说,频繁的IO读写,创建过多的线程,CPU都会较高,而线程死锁或者死循环基本是导致cpu高的罪魁祸首。
程序测试
本人在Windows上编写了一个测试程序
package cn.wideth.buz.utils;
public class MyThread implements Runnable{
@Override
public void run() {
long i = 0;
//死循环会导致不断的IO操作,造成CPU偏高
while(true){
i++;
if(i % 1000000 == 0){
System.out.println(Thread.currentThread().getName() + " -->" + i);
}
}
}
public static void main(String[] args) {
for(int i = 0; i < 3; i++){
MyThread myThread = new MyThread();
Thread thread = new Thread(myThread);
thread.start();
}
}
}
问题定位
由于程序是在window上编写的测试程序,所以先到任务管理器中找到CPU占用比较高的进程的PID,如果是LINUX环境下,直接使用top命令得到进程占用比较多PID即可。
使用jstack -l PID命令得到定位线程信息
将线程信息保存在一个临时文件中,使用命令jstack -l 74680 > tempfile.txt即可
从当前进程的堆栈信息中定位到CPU占用比较高的代码
本文小结
如果线上出现了CPU过高的情况,一般是代码中出现了无限循环等情况。可以先找到CPU占用比较多的进程id,Linux中使用top命令,Windows中可以到任务管理器中查看,然后使用jstack -1 PID命令打印进内的堆栈信息,结合代码即可找到占用CPU的问题。