java命令_Java程序员,不得不会的JDK jstack命令工具
作者:Jay_huaxiao 链接:https://juejin.im/post/5ead8067e51d454da36cf182
如果有一天,你的Java程序长时间停顿,也许是它病了,需要用jstack拍个片子分析分析,才能诊断具体什么病症,是死锁综合征,还是死循环等其他病症,本文我们一起来学习jstack命令~
- jstack 的功能
- jstack用法
- 线程状态等基础回顾
- 实战案例1:jstack 分析死锁
- 实战案例2:jstack 分析CPU 过高
jstack 的功能
jstack是JVM自带的Java堆栈跟踪工具,它用于打印出给定的java进程ID、core file、远程调试服务的Java堆栈信息.
jstack prints Java stack traces of Java threads for a given Java process orcore file or a remote debug server.
jstack命令用于生成虚拟机当前时刻的线程快照。 线程快照是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因, 如线程间死锁、死循环、请求外部资源导致的长时间等待等问题。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。 如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。 另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。
jstack用法
jstack 命令格式如下
jstack [ option ] pid jstack [ option ] executable core jstack [ option ] [server-id@]remote-hostname-or-IP
- executable Java executable from which the core dump was produced.(可能是产生core dump的java可执行程序)
- core 将被打印信息的core dump文件
- remote-hostname-or-IP 远程debug服务的主机名或ip
- server-id 唯一id,假如一台主机上多个远程debug服务
最常用的是
jstack [option] // 打印某个进程的堆栈信息
option参数说明如下:
选项 作用 -F 当正常输出的请求不被响应时,强制输出线程堆栈 -m 如果调用到本地方法的话,可以显示C/C++的堆栈 -l 除堆栈外,显示关于锁的附加信息,在发生死锁时可以用jstack -l pid来观察锁持有情况
线程状态等基础回顾
线程状态简介
jstack用于生成线程快照的,我们分析线程的情况,需要复习一下线程状态吧,拿小凳子坐好,复习一下啦~
Java语言定义了6种线程池状态:
- New:创建后尚未启动的线程处于这种状态,不会出现在Dump中。
- RUNNABLE:包括Running和Ready。线程开启start()方法,会进入该状态,在虚拟机内执行的。
- Waiting:无限的等待另一个线程的特定操作。
- Timed Waiting:有时限的等待另一个线程的特定操作。
- 阻塞(Blocked):在程序等待进入同步区域的时候,线程将进入这种状态,在等待监视器锁。
- 结束(Terminated):已终止线程的线程状态,线程已经结束执行。
Dump文件的线程状态一般其实就以下3种:
- RUNNABLE,线程处于执行中
- BLOCKED,线程被阻塞
- WAITING,线程正在等待
Monitor 监视锁
因为Java程序一般都是多线程运行的,Java多线程跟监视锁环环相扣,所以我们分析线程状态时,也需要回顾一下Monitor监视锁知识。
有关于线程同步关键字Synchronized与监视锁的爱恨情仇,有兴趣的伙伴可以看一下我这篇文章 Synchronized解析——如果你愿意一层一层剥开我的心
Monitor的工作原理图如下:
- 线程想要获取monitor,首先会进入Entry Set队列,它是Waiting Thread,线程状态是Waiting for monitor entry。
- 当某个线程成功获取对象的monitor后,进入Owner区域,它就是Active Thread。
- 如果线程调用了wait()方法,则会进入Wait Set队列,它会释放monitor锁,它也是Waiting Thread,线程状态in Object.wait()
- 如果其他线程调用 notify() / notifyAll() ,会唤醒Wait Set中的某个线程,该线程再次尝试获取monitor锁,成功即进入Owner区域。
Dump 文件分析关注重点
- runnable,线程处于执行中
- deadlock,死锁(重点关注)
- blocked,线程被阻塞 (重点关注)
- Parked,停止
- locked,对象加锁
- waiting,线程正在等待
- waiting to lock 等待上锁
- Object.wait(),对象等待中
- waiting for monitor entry 等待获取监视器(重点关注)
- Waiting on condition,等待资源(重点关注),最常见的情况是线程在等待网络的读写
实战案例1:jstack 分析死锁问题
- 什么是死锁?
- 如何用jstack排查死锁?
什么是死锁?
死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法进行下去。
如何用如何用jstack排查死锁问题
先来看一段会产生死锁的Java程序,源码如下:
/** * Java 死锁demo */public class DeathLockTest { private static Lock lock1 = new ReentrantLock(); private static Lock lock2 = new ReentrantLock(); public static void deathLock() { Thread t1 = new Thread() { @Override public void run() { try { lock1.lock(); System.out.println(Thread.currentThread().getName() + " get the lock1"); Thread.sleep(1000); lock2.lock(); System.out.println(Thread.currentThread().getName() + " get the lock2"); } catch (InterruptedException e) { e.printStackTrace(); } } }; Thread t2 = new Thread() { @Override public void run() { try { lock2.lock(); System.out.println(Thread.currentThread().getName() + " get the lock2"); Thread.sleep(1000); lock1.lock(); System.out.println(Thread.currentThread().getName() + " get the lock1"); } catch (InterruptedException e) { e.printStackTrace(); } } }; //设置线程名字,方便分析堆栈信息 t1.setName("mythread-jay"); t2.setName("mythread-tianluo"); t1.start(); t2.start(); } public static void main(String[] args) { deathLock(); }}
运行结果:
显然,线程jay和线程tianluo都是只执行到一半,就陷入了阻塞等待状态~
jstack排查Java死锁步骤
- 在终端中输入jsp查看当前运行的java程序
- 使用 jstack -l pid 查看线程堆栈信息
- 分析堆栈信息
在终端中输入jsp查看当前运行的java程序
通过使用 jps 命令获取需要监控的进程的pid,我们找到了23780 DeathLockTest
使用 jstack -l pid 查看线程堆栈信息
由上图,可以清晰看到死锁信息:
- mythread-tianluo 等待这个锁 “0x00000000d61ae3a0”,这个锁是由于mythread-jay线程持有。
- mythread-jay线程等待这个锁“0x00000000d61ae3d0”,这个锁是由mythread-tianluo 线程持有。
还原死锁真相
“mythread-tianluo"线程堆栈信息分析如下:
- mythread-tianluo的线程处于等待(waiting)状态,持有“0x00000000d61ae3d0”锁,等待“0x00000000d61ae3a0”的锁
“mythread-jay"线程堆栈信息分析如下:
- mythread-tianluo的线程处于等待(waiting)状态,持有“0x00000000d61ae3a0”锁,等待“0x00000000d61ae3d0”的锁
实战案例2:jstack 分析CPU过高问题
来个导致CPU过高的demo程序,一个死循环,哈哈~
/** * 有个导致CPU过高程序的demo,死循环 */public class JstackCase { private static ExecutorService executorService = Executors.newFixedThreadPool(5); public static void main(String[] args) { Task task1 = new Task(); Task task2 = new Task(); executorService.execute(task1); executorService.execute(task2); } public static Object lock = new Object(); static class Task implements Runnable{ public void run() { synchronized (lock){ long sum = 0L; while (true){ sum += 1; } } } }}
jstack 分析CPU过高步骤
- top
- top -Hp pid
- jstack pid
- jstack -l [PID] >/tmp/log.txt
- 分析堆栈信息
1.top
在服务器上,我们可以通过top命令查看各个进程的cpu使用情况,它默认是按cpu使用率由高到低排序的
由上图中,我们可以找出pid为21340的java进程,它占用了最高的cpu资源,凶手就是它,哈哈!
2. top -Hp pid
通过top -Hp 21340可以查看该进程下,各个线程的cpu使用情况,如下:
可以发现pid为21350的线程,CPU资源占用最高~,嘻嘻,小本本把它记下来,接下来拿jstack给它拍片子~
3. jstack pid
通过top命令定位到cpu占用率较高的线程之后,接着使用jstack pid命令来查看当前java进程的堆栈状态,jstack 21350后,内容如下:
4. jstack -l [PID] >/tmp/log.txt
其实,前3个步骤,堆栈信息已经出来啦。但是一般在生成环境,我们可以把这些堆栈信息打到一个文件里,再回头仔细分析哦~
5. 分析堆栈信息
我们把占用cpu资源较高的线程pid(本例子是21350),将该pid转成16进制的值
在thread dump中,每个线程都有一个nid,我们找到对应的nid(5366),发现一直在跑(24行)
这个时候,可以去检查代码是否有问题啦~ 当然,也建议隔段时间再执行一次stack命令,再一份获取thread dump,毕竟两次拍片结果(jstack)对比,更准确嘛~
整理了几百本各类技术电子书相送 ,嘘~,「免费」 送给小伙伴们,私信或者评论【666】自行领取。和一些小伙伴们建了一个技术交流群,一起探讨技术、分享技术资料,旨在共同学习进步。
java命令_Java程序员,不得不会的JDK jstack命令工具相关推荐
- chrome java插件_Java程序员喜欢的10款软件里有你在用的吗?
作为一名Java程序员,日常开发的过程中,我们需要借助很多工具来进行编码.好的工具可以极大的提升程序员的工作效率,今天我们来认识下大多数程序员喜欢的10款软件.持不同意见或有想要补充的小伙伴,欢迎评论 ...
- java书籍_Java程序员必看的 13 本 Java 书籍!
原文:Java程序员必看的 13 本 Java 书籍! 作者: java技术栈 关乎于程序员,除了做项目来提高自身的技术,还有一种提升自己的专业技能就是:多!看!书! 毕竟,书是学习的海洋呢!So,J ...
- tomcat如何修改java版本_Java程序员必备——Tomcat配置技巧Top10
一.配置系统管理(Admin Web Application) 大多数商业化的J2EE服务器都提供一个功能强大的管理界面,且大都采用易于理解的Web应用界面.Tomcat按照自己的方式,同样提供一个成 ...
- java过剩_Java程序员的未来发展之路,你是否感到迷茫?你不知道的Java现状
Java的生态圈决定了这门语言在未来10年都会是最热门的语言之一,因为Java技术具有卓越的通用性.高效性.安全性和平台移植性,它可以跨平台的应用到不同的领域,工作需求足够大. 但也有很多人一直在说J ...
- java走向_Java 程序员走向“人生巅峰”的20个建议
作为一个程序员,在提高自己技能的同时,也要提高自己的思维方式.以下20条建议,可以帮助我们成为一个专业的coder,专业的技术人员. (1) 熟悉工具 军人手中有枪,农民手中有锄头,而我们手中有Jav ...
- java查看日志命令_Java程序员必备:查看日志常用的linux命令
前言 趁周末,复习一下鸟哥的linux私房菜,看了文件内容查阅部分,做个笔记,哈哈,希望对你有帮助哦. cat cat : 由第一行开始显示文件所有内容 参数说明cat[-AbEnTv] 参数: -A ...
- java葵花宝典_JAVA程序员想入职跳槽,这些基本功一定要做好,你给自己打几分?...
基础篇 Q1 访问修饰符 public , private , protected 以及不写时的区别? 类的成员不写访问修饰符时,默认的是default. Q2 Stirng是最基本的数据类型吗? 不 ...
- 现在的游戏都是java吗_Java程序员:工作还是游戏,是该好好衡量一下了
前阵子我终于下定决心,删掉了硬盘里所有的游戏. 身为一个程序猿,每天都要和各种新技术打交道,闲暇时间,总还得看一下各大论坛,逛逛博客园啥的,给自己充充电.游戏的话,其实我自小就比较喜欢,可以算是一种兴 ...
- java职级_Java程序员等级怎么划分?
技术不同.简单的可以理解为:初级中级的只关注代码,编程.高级的就要考虑系统的架构,整体框架. 一.初级部分 1.Java 程序设计基础,包括 J2sdk基础.Java面向对象基础.Java API使用 ...
最新文章
- Java 判断list中是否包含某个元素
- 设置***遇到一个小问题
- 预备作业02 20162320刘先润
- python创建txt文件
- 如何让带有批注等修改痕迹的word文档编程“正规”文档?
- java 时间格式化_彻底解决Spring mvc中时间的转换和序列化等问题
- scala教程之:可见性规则
- 第六节:用audio标签打造一个属于自己的HTML5音乐播放器
- 自动化构建部署之Jenkins安装【Docker容器】
- linux网络流量监测工具,linux下网络流量监控工具
- 20154319 实验九web安全基础实践
- 第三章CDMA的原理和应用(1)
- python作排产计划_排产计划表
- JAVA Reflect反射详解
- 123457123456#0#-----com.yuming.HitMouse01--前拼后广--幼儿打地鼠游戏
- 4 java多线程和高并发(待更新)
- VirtualBox虚拟电脑控制台错误,不能为虚拟电脑打开一个新任务
- Android 模拟器中的menu键
- Excel公式提取数据
- 毛利率、净利率和成本利润率的区别是什么 ?
热门文章
- Bailian2698 八皇后【回溯】
- AOJ0008 Sum of 4 Integers【暴力】
- NUC1154 Vertical Histogram【打印图案】
- Python 爬虫 —— 文件及文件夹操作
- 数据科学(data science)概览
- [面试] 算法(七)—— 逆序输出链表
- 黄金分割比的重新理解
- python 模块定义_在python中定义私有模块函数
- qml中使用combobox实现多级菜单_Excel教程:还不会做Excel三级下拉菜单?其实它跟复制粘贴一样简单...
- vector java 复制_Java代码性能优化的 40+ 细节