JAVA CPU100%与线程死锁定位

前言

CPU100%和线程死锁都是造成系统运行缓慢、假死的原因之一。这里讲解下如果发生这种情况如何定位。

CPU100%定位

CPU100%环境模拟

首先我们给出如下代码模拟出CPU100%

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个线程。

线程定位

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

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

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

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

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

线程死锁定位

jstack可以查看线程状态,所以也可以定位死锁问题。

死锁环境模拟

首先我们给出如下代码构造死锁,死锁线程分别命名为deadLock-1、deadLock-2

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线程都处于阻塞状态,最下面会直接给出死锁信息

转载于:https://juejin.im/post/5cfde465f265da1b897ac430

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值