CPU 100%排查及常见案例

CPU 100%排查及常见案例

这篇文章主要分享一般线上项目遇到CPU%时排查的方式,并提供了几个典型案例来帮助大家熟悉排查过程,我会先以 “死循环” 为例子来为大家演示一遍整体的排查流程

目录

  • CPU 100%排查及常见案例
    • 一、排查方式介绍
      • 1.top 命令查看CPU占用100%的进程号(PID)
      • 2. top -H -n 1 -p PID 然后通过命令查找对应进程下线程的状态
      • 3.然后通过 jstack -l PID > ./jstack.log 命令输出进程的线程文件
      • 4.查看刚输出的jstack.log文件,查看线程详情
    • 二.案例介绍
      • 1.死循环
      • 2.死锁
      • 3.耗时的计算
      • 4.频繁的FULL GC
    • 三、JVM系列文章

一、排查方式介绍

1.top 命令查看CPU占用100%的进程号(PID)

在这里插入图片描述
如果java服务有多个可以通过ps -aux|grep java 命令来找到对应服务的进程号(PID)
在这里插入图片描述

2. top -H -n 1 -p PID 然后通过命令查找对应进程下线程的状态

可以看到3418线程cpu极高
CPU 100%排查及常见案例_第1张图片

3.然后通过 jstack -l PID > ./jstack.log 命令输出进程的线程文件

注意这里的PID 是进程号 ,这里我是3400

在这里插入图片描述

4.查看刚输出的jstack.log文件,查看线程详情

注意这里的线程PID是第二步PID,还要转成16进制

例如:我这里PID就是3418 转成16进制就是 d5a

我是通过vim 命令查看log文件,可以 /+字符串 例如:/d5a 直接向下搜索所在位置,可以看到此线程正在运行中,且代码行数也标注清楚

CPU 100%排查及常见案例_第2张图片

二.案例介绍

这里案例都参照上面的步骤来,不再一一演示,只放结果·

1.死循环

    /**
     * 死循环
     * @return
     */
    @GetMapping("/deadCycle")
    public String deadCycle(){
        for(int i=1;i>0;i++){
            System.out.println(i);
        }
        return "Success";
    }

CPU 100%排查及常见案例_第3张图片

2.死锁

正常一个死锁是不会导致cpu 100%的,除非很多线程死锁或者一直自旋获取锁,这里为了演示直接搞了个极端的例子

/**
     * 死锁
     * @return
     */
    @GetMapping("/deadLock")
    public String deadLock(){
        Lock lock1=new ReentrantLock();
        //线程t1中
        new Thread(()->{
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            while (!lock1.tryLock()){
                System.out.println("线程1 一直自旋获取锁");
            }
            System.out.println("线程1 获取到锁 do something");
        }).start();

        // 线程2
        new Thread(()->{
            lock1.lock();  //此时线程2 获取到锁 但是一直阻塞 导致锁无法释放
            while (true){

            }
        }).start();

        return "Success";
    }

CPU 100%排查及常见案例_第4张图片

CPU 100%排查及常见案例_第5张图片

3.耗时的计算

/**
     * 耗时计算
     * @return
     */
    @GetMapping("/timeConsuming")
    public String timeConsuming(){
        for (int a = 0; a < 5; a++) {
            new Thread(()->{
                int i = Integer.MAX_VALUE;
                double temp = 0;
                for (int j = 1; j <= i; j++) {
                    temp += Math.pow(j,j-1);
                }
            }).start();
        }
        return "Success";
    }

CPU 100%排查及常见案例_第6张图片

CPU 100%排查及常见案例_第7张图片

4.频繁的FULL GC

这种是内存问题导致的CPU 问题,所以放到之后的内存问题排查里了

使用jmeter工具并发请求

private static ThreadLocal threadLocal=new ThreadLocal();
/**
     * ThreadLocal内存溢出 测试
     * @return
     */
    @GetMapping("/fullGc")
    public String fullGc(){
        for (int a = 0; a < 5; a++) {
            //一次性产生5个8m 对象
            threadLocal.set(new FullGcTest(new Byte[1024*1024*8]));
        }
        return "Success";
    }

三、JVM系列文章

  • (一)CPU 100%排查及常见案例
  • (二)内存 100%排查及常见案例
  • (三)JVM内存调优-实践测试

你可能感兴趣的:(linux,java,jvm)