美文网首页
jstack的使用

jstack的使用

作者: binecy | 来源:发表于2019-03-23 10:49 被阅读0次

jstack命令主要打印指定Java进程的线程堆栈跟踪信息。它是一个很有用的命令。

检测死锁

编写一个导致死锁的简单栗子

public class DeadLockTest {
    public static void main(String[] args) {
        ReentrantLock lock1 = new ReentrantLock();
        ReentrantLock lock2 = new ReentrantLock();
        ExecutorService service = Executors.newCachedThreadPool();

        service.execute(() -> {
            lock1.lock();
            ThreadUtil.sleepIgnoreException(1000);
            lock2.lock();

            lock2.unlock();

            lock1.unlock();

        });

        service.execute(() -> {
            lock2.lock();
            ThreadUtil.sleepIgnoreException(1000);
            lock1.lock();
            lock1.unlock();

            lock2.unlock();
        });
    }
}

ThreadUtil.sleepIgnoreException可以sleep当前线程,并忽略InterruptedException异常,为了节省代码篇幅抽取了这个方法。

jps查看PID

$ jps
3876 DeadLockTest

通过jstack查看死锁信息

$ jstack 3876
...

Found one Java-level deadlock:
=============================
"pool-1-thread-2":
  waiting for ownable synchronizer 0x00000000efa39c50, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),
  which is held by "pool-1-thread-1"
"pool-1-thread-1":
  waiting for ownable synchronizer 0x00000000efa39c80, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),
  which is held by "pool-1-thread-2"

Java stack information for the threads listed above:
===================================================
"pool-1-thread-2":
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000000efa39c50> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
    at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)
    at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
    at com.binecy.lock.DeadLockTest.lambda$main$1(DeadLockTest.java:33)
    at com.binecy.lock.DeadLockTest$$Lambda$2/2074407503.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
"pool-1-thread-1":
    ...

Found 1 deadlock.

可以通过堆栈信息查看发生死锁的代码位置。

分析占用CPU过高的线程

编写一个严重占用CPU的栗子

public class CpuHighTest {
    public static void main(String[] args) {
        ExecutorService service = Executors.newCachedThreadPool();
        service.execute(()->{
            int i = 0;
            while (true)
                i++;
        });
        service.execute(() -> {
            int i = 0;
            while (true) {
                i++;
                ThreadUtil.sleepIgnoreException(1000);
            }
        });
    }
}

JPS查看PID

$ jps
4260 CpuHighTest

通过top -H -p 4260查看(-H表示展示线程信息)

...
  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND      
 4286 binecy    20   0 3350548  20124   4280 R 99.3  0.6   1:38.17 java         
 4260 binecy    20   0 3350548  20124   4280 S  0.0  0.6   0:00.00 java         
...   

PID为 4286 的线程严重占用cpu。
将PID 4286 转换为16进制 10be

通过jstack查看对应的线程信息

$ jstack  4260
...
"pool-1-thread-1" #10 prio=5 os_prio=0 tid=0x00007fe4b026b000 nid=0x10be runnable [0x00007fe49cef1000]
   java.lang.Thread.State: RUNNABLE
    at com.binecy.lock.CpuHighTest.lambda$main$0(CpuHighTest.java:12)
    at com.binecy.lock.CpuHighTest$$Lambda$1/558638686.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

nid=0x10be这里就是上面的PID。
这里也可以通过堆栈信息找到对应的代码位置

参考:
如何使用jstack分析线程状态

相关文章

  • jstack使用

    使用jstack分析指定应用线程使用异常排除。 使用jstack命令dump线程信息,例如查看Pid为3117的进...

  • jstack的使用

    jstack简介 通过jstack,我们可以轻松得知jvm中各个线程的工作情况. 工作情况 jstack -l p...

  • jstack的使用

    jstack命令主要打印指定Java进程的线程堆栈跟踪信息。它是一个很有用的命令。 检测死锁 编写一个导致死锁的简...

  • jstack的使用

    参考来源[https://www.cnblogs.com/yangzhixue/p/11989863.html] ...

  • 【Kafka】排查进程无法Jstack

    1. 背景 通过jstack分析kafka堆栈信息时,发现jstack无法使用,并且提示如下异常: 2. 分析 查...

  • jstack使用小结

    搬运自https://www.toutiao.com/i6664464807451689475/ jstack小工...

  • 分析程序死锁及定位

    检测程序死锁 可以使用jstack命令, jstack you_pid进程的pid可以在任务管理器中找到,你也可以...

  • [转]jstack线程dump输出状态解释

    执行jstack命令,将得到进程的堆栈信息。我一般使用jstack -l pid来得到长列表,显示其详细信息。有时...

  • 死锁问题排查

    首先使用jps查询进程ID然后使用jstack和进程ID查询堆栈日志信息。

  • jstack命令解析

    jstack用法 jstack查看输出 jstack统计线程数 jstack检测死锁 死锁代码 死锁日志 jsta...

网友评论

      本文标题:jstack的使用

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