jvm 性能调优工具之 jstack

作者: jijs | 来源:发表于2018-01-25 23:52 被阅读265次

    概述

    jstack是jdk自带的线程堆栈分析工具,使用该命令可以查看或导出 Java 应用程序中线程堆栈信息。

    Jstack 用法

    image

    参数说明:

    • -l 长列表. 打印关于锁的附加信息,例如属于java.util.concurrent 的 ownable synchronizers列表.

    • -F 当’jstack [-l] pid’没有相应的时候强制打印栈信息

    • -m 打印java和native c/c++框架的所有栈信息.

    • -h | -help 打印帮助信息

    pid 需要被打印配置信息的java进程id,可以用jps查询.

    Jstack 使用

    通过使用 jps 命令获取需要监控的进程的pid,然后使用 jstack pid 命令查看线程的堆栈信息。

    image

    通过 jstack 命令可以获取当前进程的所有线程信息。

    每个线程堆中信息中,都可以查看到 线程ID、线程的状态(wait、sleep、running 等状态)、是否持有锁信息等。

    死锁示例

    下面通过一个例子,来演示 jstack 检查死锁的一个例子,代码如下:

    public static void deathLock() {
        Thread t1 = new Thread() {
            @Override
            public void run() {
                try {
                    lock1.lock();
                    TimeUnit.SECONDS.sleep(1);
                    lock2.lock();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        Thread t2 = new Thread() {
            @Override
            public void run() {
                try {
                    lock2.lock();
                    TimeUnit.SECONDS.sleep(1);
                    lock1.lock();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        t1.setName("mythread1");
        t2.setName("mythread2");
        t1.start();
        t2.start();
    }
    

    使用 jstack -l pid 查看线程堆栈信息,发现在堆栈信息最后面检查出了一个死锁。如下图

    可以清楚的看出 mythread2 等待 这个锁 “0x00000000d6eb82d0”,这个锁是由于mythread1线程持有。

    mythread1线程等待这个锁“0x00000000d6eb8300”,这个锁是由mythread2线程持有。

    “mythread1”线程堆栈信息如下:

    可以看出当前线程持有“0x00000000d6eb82d0”锁,等待“0x00000000d6eb8300”的锁

    “mythread2”线程堆栈信息如下:

    “mythread2”的堆栈信息中可以看出当前线程持有“0x00000000d6eb8300”锁,等待“0x00000000d6eb82d0”的锁。

    个人微信公众号:

    相关文章

      网友评论

        本文标题:jvm 性能调优工具之 jstack

        本文链接:https://www.haomeiwen.com/subject/rwabaxtx.html