当前位置 > it书童 > java > 正文

jstack 的使用

java it书童 2020-12-24 21:36:34 0赞 0踩 395阅读 0评论

有些时候我们需要查看下jvm中的线程执行情况,比如,发现服务器的CPU的负载突然增高了、出现了死锁、死循环等,我们该如何分析呢

由于程序是正常运行的,没有任何的输出,从日志方面也看不出什么问题,所以就需要 看下jvm的内部线程的执行情况,然后再进行分析查找出原因

这个时候,就需要借助于jstack命令了,jstack的作用是将正在运行的jvm的线程情况进 行快照,并且打印出来

$ jstack 4628

编写代码,启动2个线程,Thread1拿到了obj1锁,准备去拿obj2锁时,obj2已经被 Thread2锁定,所以发送了死锁

public class TestDealLock {
    private static Object obj1 = new Object();
    private static Object obj2 = new Object();

    public static void main(String[] args) {
        new Thread(new Thread1()).start();
        new Thread(new Thread2()).start();
    }

    private static class Thread1 implements Runnable{
        @Override
        public void run() {
            synchronized (obj1) {
                System.out.println("Thread1 拿到了 obj1 的锁");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (obj2) {
                    System.out.println("Thread1 拿到了 obj2 的锁");
                }
            }
        }
    }

    private static class Thread2 implements Runnable{
        @Override
        public void run() {
            synchronized (obj2) {
                System.out.println("Thread1 拿到了 obj2 的锁");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (obj1) {
                    System.out.println("Thread1 拿到了 obj1 的锁");
                }
            }
        }
    }
}

两个线程互相拿着对方所要的锁,一直死磕,导致程序僵死

查看程序进程

$ jps -l
4628 org.apache.catalina.startup.Bootstrap
7271 sun.tools.jps.Jps
5675
5884
7134 org.jetbrains.jps.cmdline.Launcher
7135 com.itshutong.jvm.TestDealLock

用 jstack 分析

$ jstack 7135

明显看到两个线程互相在等待

关于我
一个文科出身的程序员,追求做个有趣的人,传播有价值的知识,微信公众号主要分享读书思考心得,不会有代码类文章,非程序员的同学请放心订阅
转载须注明出处:https://www.itshutong.com/articles/988