性能文章>怎么排查CPU飙升>

怎么排查CPU飙升原创

3年前
8381113

怎么排查CPU飙升

线上有些系统,本来跑的好好的,突然有一天就会出现报警,CPU使用率飙升,然后重启之后就好了。例如,多线程操作一个线程不安全的list往往就会出现这种现象。那么怎么定位到具体的代码范围呢?今天笔者就教大家一个小技巧

代码准备

这次,笔者准备了一个demo代码,大致线程模型是这样的:

image.png

代码下所示:

public class CpuHighExample {

    public static void cpuHigh() {
        final List<String> list = new LinkedList<>();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                int count = 1;
                while (true) {
                    // 构造thread1为消耗很高cpu的线程
                    count = count + 1;
                }
            }
        });
        thread1.setName("thread1");
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        // 构造thread2为消耗很低cpu的线程
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        thread2.setName("thread2");
        thread1.start();
        thread2.start();
    }
}

案例运行

这个案例一运行,就听见笔者的电脑风扇起飞了,呼呼作响。直接top一下

image.png

果然是java进程,占用最高,CPU 100%了(占用了一个核),而其PID是2717,正是我们跑的例子。那么下一步,我们就需要定位到底是那一个线程在耗CPU

top -H
Threads toggle
            Starts top with the last remembered ’H’ state reversed.  When this
            toggle  is  On,  all individual threads will be displayed.  Other-
            wise, top displays a summation of all threads in a process.

如man文档所描述,top -H可以打印出线程信息,我们就top -H一下。

image.png

图中可以看到,占用最高的线程PID是2727,同时线程名是thread1。

继续jstack

我们知道jstack可以dump出jvm所有线程运行的快照,然后我们就可以通过刚才获取的PID去定位到jstack那个进程。

// 注意,这边用top出来的进程号2717,而不是top -H出来的2727
jstack 2717 > 1.txt

由于jstack打印出的线程号是以16进制的形式表现的,所以我们对2727的线程号做一次转换,得到aa7。

image.png

然后我们在1.txt中搜索2727,这里用的是less然后进去后搜索,而不是用grep。因为这样比较直观的能看出之前和之后的信息。less下

image.png

image.png

我们找到aa7后,就直接能发现代码一直跑在CpuHighExample.java第19行上面。

image.png

当然了,我们需要多jstack几次,如果每次jstack出来都刚好在这段代码左右,那么基本可以证明,是这段代码导致CPU飙升了。

总结

CPU突然飙升这个问题,我们很容易通过top -H和jstack找到对应的代码范围,这无疑极大的缩小了我们的定位范围。

image.png

点赞收藏
分类:标签:
巡山小汪

关注微信公众号《解Bug之路》,有问题请在公众号中咨询:) 无论多么艰苦的时刻,都不要忘记,辉煌的未来,在你的眼中闪耀!

请先登录,查看1条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步

为你推荐

随机一门技术分享之Netty

随机一门技术分享之Netty

MappedByteBuffer VS FileChannel:从内核层面对比两者的性能差异

MappedByteBuffer VS FileChannel:从内核层面对比两者的性能差异

13
1