java进程cpu使用率高问题排查

以下对近期排查了一个生产cpu使用率高问题做个复盘:

简单说下过程
1、top查看耗时大进程
2、再top -Hp 进程id,查看耗时高的线程。
3、printf “%x\n” 线程id 转16进制,比如这里是4a71
4、jstack 19022 | grep 4a71 -A 50 找到线程执行栈信息。也可以jstack -l 进程号,看所有的,排查可疑。

jstack信息如下:
java进程cpu使用率高问题排查
定位到关键代码:
java进程cpu使用率高问题排查

找到代码位置:
java进程cpu使用率高问题排查
再往下看:
java进程cpu使用率高问题排查
这里是可疑代码,通过日志信息中的业务代码入口,找到了相对的Excel模板。发现模板整行被格式化。
本地执行验证确认了 getLastCellNumber()为一万六千多。这种情况下导出2000多行数据,即要循环4千万次左右。

这里的处理方式:
1、替换了格式模板,实际有效列十几列
2、对有效列数做了限定提示,不超50列。

后记

对应循环上千万次的效率,可以做个简单验证,这里以本地设备,执行循环输出一千万为例:

public class TestLoop {

    public static void main(String[] args){

        long start = System.currentTimeMillis();
        int i = 0;
        while(i < 10000000){
            System.out.println(i);
            i++;
        }

        System.out.println((System.currentTimeMillis()-start)/1000);
    }
}

输出结果:

9999995
9999996
9999997
9999998
9999999
64

Process finished with exit code 0

耗时64s。
所以循环及循环中的操作,要慎重考量。

上一篇:使用jstack命令查看CPU高占用的问题记录


下一篇:linux使用jstack来找出死循环的java代码