jdk-jstack命令

jstack 命令详解

jstack命令用来生成JVM中的线程快照(thread dump),其中包含有每个线程的方法调用栈以及其状态、锁信息等。其用法说明如下所示。
在这里插入图片描述
说明一下三个参数的含义:
-F:如果正常执行jstack命令没有响应(比如进程hung住了),可以加上此参数强制执行thread dump。
-m:除了打印Java的方法调用栈之外,还会输出native方法的栈帧。
-l:打印与锁有关的附加信息。使用此参数会导致JVM停止时间变长,在生产环境需慎用。

jstack是在线程级别定位JVM问题的利器,但前提是得读懂thread dump,我们举例说明。

线程快照

在这里插入图片描述
在每个线程的快照的第一行,包含有线程名、是否为守护线程、优先级、线程ID等信息,第二行则是线程状态,下面就是方法调用栈了。下图是Java线程状态转换的示意,老生常谈。
在这里插入图片描述
jstack线程快照中的状态与图示相同,只是没有NEW状态而已。我们逐一进行分析,在分析之前,先放出Java管程对象ObjectMonitor的简图。看官也可以通过我之前写的这篇文章来了解管程。
在这里插入图片描述

RUNNABLE

线程正在运行。如果在其调用栈中看到locked <地址>的提示,表示该方法正持有锁,即该线程位于Owner区内。

BLOCKED

线程处于阻塞状态,即正在等待锁被其他线程释放。在其调用栈的栈顶方法会看到waiting to lock <地址>的提示,表示该方法试图持有锁,线程正在Entry Set区等待。

WAITING

线程处于无限等待的状态。又分为两种情况:

  • on object monitor:线程已经获得锁,调用了不带超时参数的Object.wait()/Thread.join()方法,线程进入管程的Wait Set区。在其调用栈中会看到locked <地址>的提示。
  • parking:调用了LockSupport.park()方法,线程直接进入挂起状态(park是Unsafe提供的低级原语)。在其调用栈的栈顶方法会看到parking to wait for <地址>的提示。

TIMED_WAITING

线程处于有限等待的状态。它分为三种情况,除了与WAITING相同的on object monitor(获得锁并调用带超时的Object.wait()/Thread.join()方法)和parking(调用带超时的LockSupport.parkNanos()/parkUntil()方法)之外,还有一种sleep,即通过Thread.sleep()使线程睡眠。

通过分析线程快照的状态和调用栈,可以让我们快速地定位造成Java程序表现异常的症结,如死锁、热锁(很多线程竞争同一块临界区造成大量BLOCKED)、高CPU占用、I/O长时间阻塞(注意此时线程状态可能是RUNNABLE)等。下面举两个具体的例子。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值