Java工具 Jstack 的使用

2023-11-08

jstack - Prints Java thread stack traces for a Java process, core file, or remote debug server.

Jstack 主要的作用是生成当前进程中所有线程的信息,也就是当前时刻 JVM 的线程快照,通过线程的信息我们可以定位到程序中出现长时间停顿、CPU 占用率过高等问题。

线程快照中的信息是当前 java 虚拟机内每一条线程正在执行的方法的堆栈集合,有了堆栈信息我们就可以分析出我们的程序问题出现在那,比如线程间死锁、外部资源请求时间过长、死循环等。

使用:

jstack [ options ] pid

jstack [ options ] executable core

jstack [ options ] [ server-id@ ] remote-hostname-or-IP


OPTIONS
       -F
              Force a stack dump when jstack [-l] pid does not respond.

       -l
              Long listing. Prints additional information about locks such as a list of owned java.util.concurrent ownable synchronizers. See the
              AbstractOwnableSynchronizer class description at
              http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/AbstractOwnableSynchronizer.html

       -m
              Prints a mixed mode stack trace that has both Java and native C/C++ frames.
  • -F 当正常的请求不被响应时,强制输出堆栈信息。
  • -l 额外打印锁的信息,当发生死锁是可以查看锁的信息
  • -m 如果调用本地方法栈的信息,可以打印 C/C++的堆栈

以一个发生死锁的例子来看一下使用 Jstack 查看到的信息

public class Jstack {

    private static Object obj1 = new Object();
    private static Object obj2 = new Object();

    public static void main(String[] args) {

        new Thread(() -> {
            synchronized (obj1) {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (obj2) {
                }
            }
        }).start();
        new Thread(() -> {
            synchronized (obj2) {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (obj1) {
                }
            }
        }).start();
    }
}

上面代码中,第一个线程拿到 obj1 的锁,等待 obj2 的锁,第二个线程拿到 obj2 的锁,等待 obj1 的锁,这样就会发生死锁。

先通过jps命令获取到先拿到当前的进程 pid,然后通过 jstack 获取线程的信息。可以看到有两个线程都处于阻塞状态。

"Thread-1" #12 prio=5 os_prio=0 tid=0x00007fdff871c800 nid=0x3cc2 waiting for monitor entry [0x00007fdfce0fc000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at com.example.demo.jstack.Jstack.lambda$main$1(Jstack.java:36)
	- waiting to lock <0x000000076e925a90> (a java.lang.Object)
	- locked <0x000000076e925aa0> (a java.lang.Object)
	at com.example.demo.jstack.Jstack$$Lambda$2/2052001577.run(Unknown Source)
	at java.lang.Thread.run(Thread.java:748)

"Thread-0" #11 prio=5 os_prio=0 tid=0x00007fdff871a800 nid=0x3cc1 waiting for monitor entry [0x00007fdfce1fc000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at com.example.demo.jstack.Jstack.lambda$main$0(Jstack.java:25)
	- waiting to lock <0x000000076e925aa0> (a java.lang.Object)
	- locked <0x000000076e925a90> (a java.lang.Object)
	at com.example.demo.jstack.Jstack$$Lambda$1/1174361318.run(Unknown Source)
	at java.lang.Thread.run(Thread.java:748)

第一行显示可线程名、线程优先级、线程 id、线程状态描述等信息

第二行显示的是当前线程的状态

​ Java 中线程的状态分为 NEW、RUNNABLE、BLOCKED、WATING、TIMED_WATING、TERMINATED,但是在快照中 NEW 状态是不会出现的。

再下面的就是当前线程的调用栈的信息。调用栈中包含了锁的信息。

locked 表示使用 synchronized 申请对象锁成功,监视器的拥有者

waiting to lock 表示使用 synchronized 申请对象锁未成功,进入等待区。

waiting on 表示用 synchronized 申请对象锁成功后,调用了 wait 方法,进入对象的等待区等待。

parking to wait for park 是基本的线程阻塞原语,不通过监视器在对象上阻塞。随 concurrent 包会出现的新的机制,与 synchronized 体系不同。

在最后也显示出了代码中出现死锁的信息

Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x00007fdfac006638 (object 0x000000076e925a90, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x00007fdfac003da8 (object 0x000000076e925aa0, a java.lang.Object),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
	at com.example.demo.jstack.Jstack.lambda$main$1(Jstack.java:36)
	- waiting to lock <0x000000076e925a90> (a java.lang.Object)
	- locked <0x000000076e925aa0> (a java.lang.Object)
	at com.example.demo.jstack.Jstack$$Lambda$2/2052001577.run(Unknown Source)
	at java.lang.Thread.run(Thread.java:748)
"Thread-0":
	at com.example.demo.jstack.Jstack.lambda$main$0(Jstack.java:25)
	- waiting to lock <0x000000076e925aa0> (a java.lang.Object)
	- locked <0x000000076e925a90> (a java.lang.Object)
	at com.example.demo.jstack.Jstack$$Lambda$1/1174361318.run(Unknown Source)
	at java.lang.Thread.run(Thread.java:748)

Found 1 deadlock.

好了,熟悉了 Jstack,我们用一段死循环的代码,通过 Jstack 来定位到使 CPU 占用 100%的代码行

public class JstackDemo {
    public static Executor executor = Executors.newFixedThreadPool(3);
    private static Object lock = new Object();

    public static void main(String[] args) {
        Task task1 = new Task();
        Task task2 = new Task();
        executor.execute(task1);
        executor.execute(task2);
    }

    public static class Task implements Runnable {

        @Override
        public void run() {
            synchronized (lock) {
                run0();
            }
        }

        private void run0() {
            int i = 0;
            while (true) {
                i++;
            }
        }
    }
}

1、首先通过top查看到使 CPU 占用到 100%的进程 id

2、使用top -Hp 进程id 查看占用 CPU 最多的线程 id

3、将线程 id 转换为 16 进制

17997 -> 464d

4、使用 Jstack 查看 Java 所在的进程,并找到相应的线程

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java工具 Jstack 的使用 的相关文章

随机推荐

  • 小猴吃苹果-第12届蓝桥杯Scratch选拔赛真题精选

    导读 超平老师计划推出Scratch蓝桥杯真题解析100讲 这是超平老师解读Scratch蓝桥真题系列的第90讲 蓝桥杯选拔赛每一届都要举行4 5次 和省赛 国赛相比 题目要简单不少 再加上篇幅有限 因此我精挑细选了一部分题目进行解读 第1
  • Python-OpenCV实战一(安装)

    OpenCV简介 用深度学习做图像处理的过程中 我们常常需要用到opencv库 OpenCV是计算机视觉领域应用最广泛的开源工具包 基于C C 支持Linux Windows MacOS Android iOS 并提供了Python Mat
  • 云计算与大数据第16章 分布式内存计算平台Spark习题

    第16章 分布式内存计算平台Spark习题 16 1 选择题 1 Spark是Hadoop生态 B 组件的替代方案 A Hadoop B MapReduce C Yarn D HDFS 2 以下 D 不是Spark的主要组件 A Drive
  • 做一个属于自己的坐标系的高德地图(GIS)

    第一步 创建node环境 第二步 创建一个html文件 第三步 引入高德的样式和行为依赖 第四步 创建容器让地图挂载在上边 div div 第五步 先把地图渲染出来 const gaode new ol layer Tile title 高
  • Nginx通俗易懂教程

    不会写配置的小伙伴可以看看反向代理神器 Nginx Proxy Manager这篇博文 Nginx简介 Nginx engine x 是一个高性能的HTTP和反向代理web服务器 同时也提供了IMAP POP3 SMTP服务 Nginx是由
  • redhat安装oracle11g单实例软件建库

    1 打开xmanager passive 2 oracle 用户登录 开始安装 root rhel64 database su oracle oracle rhel64 evn grep oracle bash evn command no
  • 面试官:select......for update会锁表还是锁行?

    您好 我是路人 更多优质文章见个人博客 http itsoku com select查询语句是不会加锁的 但是select for update除了有查询的作用外 还会加锁呢 而且它是悲观锁 那么它加的是行锁还是表锁 这就要看是不是用了索引
  • 全国计算机等级考试题库二级C操作题100套(第83套)

    第83套 给定程序中 函数fun的功能是 找出100至x x 999 之间各位上的数字之和为15的所有整数 然后输出 符合条件的整数个数作为函数值返回 例如 当n值为500时 各位数字之和为15的整数有 159 168 177 186 19
  • Code Llama 是Meta 开源基于 Llama 2 的 AI 代码生成大模型

    Code Llama 可根据代码和自然语言提示生成代码和有关代码的自然语言 支持多种主流编程语言 包括 Python C Java PHP Typescript Javascript C 和 Bash https ai meta com b
  • nmap、X-Scan漏洞扫描和Metasploit中用永恒之蓝漏洞入侵靶机并上传冰河

    一 实验目的 利用nmap X Scan扫描靶机的漏洞 在Metasploit中用扫描出的永恒之蓝漏洞入侵靶机 建立连接后上传冰河控制靶机 最后用冰河陷阱清除靶机的冰河 记一次完整的入侵控制实验 二 实验环境 工具软件 VMware nma
  • 2023年MySQL-8.0.34保姆级安装教程

    重点放前面 演示环境为windows环境 MySQL社区版本安装教程如下 一 MySQL安装包下载 二 安装配置设置 三 配置环境变量 大体分为3个步骤 安装包的下载 安装配置设置 配置环境变量 一 MySQL安装包下载 下载官网地址 ht
  • 什么是SSAS?

    一 Analysis Services Analysis Services是用于决策支持和BI解决方案的数据引擎 它提供报表和客户端中使用的分析数据 它可在多用途数据模型中创建高性能查询结构 业务逻辑和KPI 企业关键绩效指标 该数据模型可
  • 第7章 高性能门户首页构建

    mini商城第7章 高性能门户首页构建 一 课题 高性能门户建设 二 回顾 1 了解文件存储系统的概念 2 了解常用文件服务器的区别 3 掌握Minio的应用 三 目标 1 OpenResty 百万并发站点架构 OpenResty 特性介绍
  • Map接口-HashMap、Hashtable和Properties

    1 Map 接口和常用方法 1 1Map 接口实现类的特点 很实用 注意 这里讲的是JDK8的Map接口特点 1 Map与Collection并列存在 用于保存具有映射关系的数据 Key Value Map 中的key 和 value可以是
  • java学习之面向对象

    面向对象 Object Oriented 是软件开发方法 一种编程范式 面向对象是相对于面向过程来讲的 面向对象方法 把相关的数据和方法组织为一个整体来看待 从更高的层次来进行系统建模 更贴近事物的自然运行模式 1 1对象 任何具有状态和行
  • python笔记15--常见定时功能

    python笔记15 常见定时功能 1 简介 2 定时方法 最粗暴的 while sleep schedule 实现定时 APScheduler 后台定时 3 注意事项 4 说明 1 简介 实际项目中经常要执行一些定时任务 因此有必要按需选
  • html5移动web开发黑马掌上商城_前端全套:黑马2019最新前端课程入门到精通【全网首发】...

    以上资源收集至互联网 如有侵权请联系删除 资源获取方式 扫码关注资源库公众号 回复密码 20190810 即可获得 截图展示 课程信息 课程难度 初级 学习人数 7942542 课程状态 已完结 时长 四个月 课程介绍 课程设计之初就对目前
  • oracle数据库表空间如何清理,oracle数据库清理临时表空间

    方法一 重启库 库重启时 Smon进程会完成临时段释放 TEMP表空间的清理操作 不过很多的时侯我们的库是不允许down的 所以这种方法缺少了一点的应用机会 不过这种方法还是很好用的 法二 Metalink给出的一个方法 修改一下TEMP表
  • 初认python-4

    文件 变量是把数据保存到内存中 如果程序重启 主机重启 内存中的数据就会丢失 要想能让数据被持久化储存 就可以把数据储存到硬盘中 也就是在文件中保存 在ws中的目录名之间使用 来分割 但是使用 来分给也是可以的 但是我们一般用 因为 在编译
  • Java工具 Jstack 的使用

    jstack Prints Java thread stack traces for a Java process core file or remote debug server Jstack 主要的作用是生成当前进程中所有线程的信息 也