JAVA CPU100%与线程死锁定位

前言

CPU100%和线程死锁都是形成系统运行缓慢、假死的缘由之一。这里讲解下若是发生这种状况如何定位。java

CPU100%定位

CPU100%环境模拟

首先咱们给出以下代码模拟出CPU100%bash

public static void main(String[] args) {
    cpuTest();
}

private static void cpuTest() {
    new Thread(() -> {
        while (true) {
            new Object();
        }
    }, "CPU-100").start();
    while (true) {
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                try {
                    new Object();
                    long random = new Random().nextInt(200);
                    Thread.sleep(random);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
复制代码

咱们要模拟的场景是一个一直忙碌的死循环线程隐藏在众多线程之中。多线程

程序逻辑:启动一个不断执行的死循环线程命名为CPU-100,另外主线程每隔200毫秒启动10个线程。dom

线程定位

执行top命令,找到java进程CPU总的使用率105.6%,进程id为22024spa

执行top -H -p 22024 查看该进程下全部线程的CPU使用率等状况。其中线程id为22041的CPU使用率99.9%。线程

执行jstack 22024 > stack.log,将该java进程的线程栈信息转储到stack.log3d

查看stack.log,能够查看当前线程信息,包括线程名、线程ID、方法、状态等。其中nid便是咱们前面找的线程id,只不过它以16进制展现。22041转16进制是0x5619 code

咱们搜索0x5619便可以定位到具体的线程,进而位到具体的程序代码

线程死锁定位

jstack能够查看线程状态,因此也能够定位死锁问题。cdn

死锁环境模拟

首先咱们给出以下代码构造死锁,死锁线程分别命名为deadLock-一、deadLock-2blog

public static void main(String[] args) {
    lockTest();
}

private static void lockTest() {
    Object o1 = new Object();
    Object o2 = new Object();
    new Thread(() -> {
        synchronized (o1) {
            try {
                Thread.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }
            synchronized (o2) {
                System.out.println("deadLock-1");
            }
        }
    },"deadLock-1").start();
    new Thread(() -> {
        synchronized (o2) {
            try {
                Thread.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }
            synchronized (o1) {
                System.out.println("deadLock-2");
            }
        }
    },"deadLock-2").start();
}
复制代码

线程定位

jcmd 找到进程id 41579

jstack 41579,发现deadLock-1,deadLock-2线程都处于阻塞状态,最下面会直接给出死锁信息

相关文章
相关标签/搜索