JVM命令之 jstack:打印JVM中线程快照

网友投稿 926 2022-11-04

JVM命令之 jstack:打印JVM中线程快照

JVM命令之 jstack:打印JVM中线程快照

学习 尚硅谷 宋红康 JVM从入门到精通 的学习笔记

概述

jstack(JVM Stack Trace)是用于生成虚拟机指定进程当前时刻的线程快照(虚拟机堆栈跟踪),线程快照就是当前虚拟机内指定进程的每一条线程正在执行的方法堆栈的集合. 生成线程的快照的作用: 多线程在执行过程中可能会出现长时间停顿的问题,线程争抢资源的时候有的线程就需要等待同步监视器或者死锁,或者死循环,等等以上情况都会导致线程不正常的情况, 会出现长时间的停顿,要想知道是哪段代码导致的线程停顿的,这个时候就需要jstack指令了

语法

基本语法 option参数:-F 当正常输出的请求不被响应时,强制输出线程堆栈 option参数:-l 除堆栈外,显示关于锁的附加信息 option参数:-m 如果调用本地方法的话,可以显示C/C++的堆栈 option参数:-h 帮助操作

演示

死锁问题排查

/** * 演示线程的死锁问题 */public class ThreadDeadLock { public static void main(String[] args) { StringBuilder s1 = new StringBuilder(); StringBuilder s2 = new StringBuilder(); new Thread(){ @Override public void run() { synchronized (s1){ s1.append("a"); s2.append("1"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (s2){ s1.append("b"); s2.append("2"); System.out.println(s1); System.out.println(s2); } } } }.start(); new Thread(new Runnable() { @Override public void run() { synchronized (s2){ s1.append("c"); s2.append("3"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (s1){ s1.append("d"); s2.append("4"); System.out.println(s1); System.out.println(s2); } } } }).start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(new Runnable() { @Override public void run() { Map all = Thread.getAllStackTraces();//追踪当前进程中的所有的线程 Set> entries = all.entrySet(); for(Map.Entry en : entries){ Thread t = en.getKey(); StackTraceElement[] v = en.getValue(); System.out.println("【Thread name is :" + t.getName() + "】"); for(StackTraceElement s : v){ System.out.println("\t" + s.toString()); } } } }).start(); }}

说明,第一个线程先获取s1锁,再获取s2锁 , 第二个线程先获取s2锁,再获取s1锁,这样就很容易出现死锁了

用命令排查

启动上面的代码

这是就打印了线程的相关信息了,

线程睡眠问题排查

public class TreadSleepTest { public static void main(String[] args) { System.out.println("hello - 1"); try { Thread.sleep(1000 * 60 * 10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("hello - 2"); }}

上面的代码会睡眠10分钟.让代码不执行

用命令排查

启动上面的main方法

多线程同步问题

/** * 演示线程的同步 */public class ThreadSyncTest { public static void main(String[] args) { Number number = new Number(); Thread t1 = new Thread(number); Thread t2 = new Thread(number); t1.setName("线程1"); t2.setName("线程2"); t1.start(); t2.start(); }}class Number implements Runnable { private int number = 1; @Override public void run() { while (true) { synchronized (this) { if (number <= 100) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ":" + number); number++; } else { break; } } } }}

上面代码说明,创建两个Number线程 ,然后去给number变量自增,其中锁对象是this, 这样就是同步

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Taira 轻量的数据 byte 序列化/反序列化工具
下一篇:简单阅读器是基于Android的小说阅读器,支持多小说源扩展。
相关文章

 发表评论

暂时没有评论,来抢沙发吧~