基本介绍
jstack 是 JDK 自带的工具,用于生成 Java 进程的线程快照,可以用来诊断 Java 应用程序的性能问题和死锁情况。下面是 jstack 的基本用法和参数介绍:
- 命令格式:
jstack [option] pid
- 参数说明:
pid
:Java 进程的进程号,用于指定要生成线程快照的目标 Java 进程,可以使用 jps 命令查看。option
:可选参数,用于指定 jstack 的具体操作选项,常用的选项包括:
-l
:除堆栈外,显示关于锁的附加信息。-F
:当 “jstack pid” 没有响应时强制输出线程栈。-m
:如果生成线程快照失败,则尝试使用操作系统级别的线程堆栈。-h
或--help
:显示 jstack 命令的帮助信息。
- 将快照信息转存至 dump(一般都是以 dump 结尾)文件:
jstack pid> 绝对或者相对路径的 dump 文件目录
- 使用示例:
- 生成线程快照:
jstack 12345
- 生成线程快照并显示关于锁的信息:
jstack -l 12345
- 强制生成线程快照:
jstack -F 12345
- 常见场景:
- 查看 Java 进程中线程的运行状态、堆栈信息,以定位性能瓶颈或死锁问题。
- 在定位 Java 进程出现假死、性能下降等问题时,生成线程快照进行分析。
实战场景:死锁定位
运行示例程序如下:
package world.xuewei; /** * 死锁示例程序 * * @author 薛伟 */ public class DeadLockDemo { private static final String A = "A"; private static final String B = "B"; public static void main(String[] args) { new DeadLockDemo().deadLock(); } private void deadLock() { new Thread(() -> { synchronized (A) { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (B) { System.out.println("1"); } } }, "Thread1").start(); new Thread(() -> { synchronized (B) { synchronized (A) { System.out.println("2"); } } }, "Thread2").start(); } }
实战场景:查看线程状态
运行示例程序如下:
package world.xuewei; import java.util.concurrent.TimeUnit; /** * 线程的生命周期 * * @author 薛伟 */ public class ThreadLifeDemo { public static final Object LOCK = new Object(); public static void main(String[] args) { // 该线程不断睡眠 new Thread(() -> { while (true) sleepSecond(100); }, "T1").start(); // 该线程在 ThreadLifeDemo.class 等待 new Thread(() -> { while (true) { synchronized (ThreadLifeDemo.class) { try { ThreadLifeDemo.class.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } }, "T2").start(); // 该线程锁住 LOCk 后不会释放 new Thread(() -> { synchronized (LOCK) { while (true) sleepSecond(100); } }, "T3").start(); // 该线程锁住 LOCk 后不会释放 new Thread(() -> { synchronized (LOCK) { while (true) sleepSecond(100); } }, "T4").start(); } /** * 睡眠指定秒数 */ public static void sleepSecond(int second) { try { TimeUnit.SECONDS.sleep(second); } catch (InterruptedException e) { e.printStackTrace(); } } }