-
jstack
2019-05-22 17:55:46声明:本人一直认为【看是一回事,做是一回事】,此篇博客是本人参考下述博客(见文末链接),进行的操作整理记录。 部分内容直接摘录自下述博客,若涉及到侵权问题,请及时联系本人。...jstack介...声明:本人一直认为【看是一回事,做是一回事】,此篇博客是本人参考下述博客(见文末链接),进行的操作整理记录。
部分内容直接摘录自下述博客,若涉及到侵权问题,请及时联系本人。目录
jstack介绍:
再次声明:此部分内容直接摘录自下述博客(见文末链接)。
-
jstack是jdk自带的线程堆栈分析工具,使用该命令可以查看或导出 java 应用程序中线程堆栈信息。
-
jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。 如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。
jstack指令:
说明:
使用方式
说明
jstack [ option ] pid
查看当前时间点,指定进程的dump堆栈信息。
jstack [ option ] pid > 文件
将当前时间点的指定进程的dump堆栈信息,写入到指定文件中。
注:若该文件不存在,则会自动生成;若该文件存在,则会覆盖源文件。
jstack [ option ] executable core
查看当前时间点,core文件的dump堆栈信息。
jstack [ option ] [server_id@]<remote server IP or hostname>
查看当前时间点,远程机器的dump堆栈信息。
可选参数说明
-F
当进程挂起了,此时'jstack [-l] pid'是没有相应的,这时候可使用此参数来强制打印堆栈信息,强制jstack),一般情况不需要使用。
-m
打印java和native c/c++框架的所有栈信息。可以打印JVM的堆栈,以及Native的栈帧,一般应用排查不需要使用。
-l
长列表. 打印关于锁的附加信息。例如属于java.util.concurrent的ownable synchronizers列表,会使得JVM停顿得长久得多(可能会差很多倍,比如普通的jstack可能几毫秒和一次GC没区别,加了-l 就是近一秒的时间),-l 建议不要用。一般情况不需要使用。
-h or -help
打印帮助信息。
简单使用示例:
jps查看java进程:
jstack查看指定进程的当前堆栈情况:
将指定进程的当前堆栈情况记录到某个文件中:
jstack实战之高cpu占用率排查:
在几乎没有什么调用的情况下,服务器cpu使用率一直居高不下,非常有可能时程序中的某个线程出现了死循环。
提示:在业务量不大的情况下,cpu占用率过高,死循环以外,常见的可能还有【内存泄漏,导致大量full GC】、
【主机cpu超卖】。此处可详见:https://mp.weixin...。准备工作:运行下述代码,死循环,造成CPU占用较高的情况。
排查开始:
第一步:使用top指令,定位CPU占用较高的进程。
第二步:使用top -H -p ${进程id}指令,查看指定进程下各个线程的cpu使用情况。
注:PID虽然名为进程控制符,但其用途不限于特指进程id。如上图中PID列指的就是线程的id。
注:上图中,线程id有一个为1956的,与进程id一样。本人怀疑main线程的id与进程id一致。
第三步:使用printf "%x" xxx指令,将1977转换为16进制。
第四步:使用jstack pid指令,查看当前的堆栈信息;并根据上一步得到的16进制的线程id,找到肇事线程。
提示:如果线程较多的话,我们可以使用grep指定来根据关键字定位行,如:
jstack 1956 | grep -10 7b9:显示【|】前面的指令打印出的信息中的,含有关键字【7b9】的那一行以及其前后各10行的数据。
注:jstack 1956 | grep 7b9:显示【|】前面的指令打印出的信息中的,含有关键字【7b9】的那一行数据。
注:jstack 1956 | grep -A10 7b9:显示【|】前面的指令打印出的信息中的,含有关键字【7b9】的那一行以及其后10行的数据。
注:jstack 1956 | grep -B10 7b9:显示【|】前面的指令打印出的信息中的,含有关键字【7b9】的那一行以及其前10行的数据。
第五步:分析肇事线程堆栈信息。
-
①线程名。
-
②线程优先级。
-
③一个地址(该地址是什么地址,存疑)。
-
④线程十六进制id。
-
⑤线程状态。
-
⑥线程当前所处方法。
-
⑦该箭头表示线程的执行历程。
-
……
注:此时,我们已经定位到了问题代码的位置⑥,接下来查看程序相应位置的代码,解决死循环问题即可。
jstack实战之死锁线程的定位:
准备工作:运行下述代码,造成死锁发生的情况。
排查开始:
第一步:使用jps指令,查看所有java进程。
第二步:使用jstack pid指令,查看指定进程的堆栈信息,观察并定位到死锁线程。
注:到这里为止,发生死锁的线程就定位到了。
注:我们可以通过诸如【统一获取锁的顺序(线程按照一定的顺序加锁)】、【设置获取锁的超时时间(线程尝试获
取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)】、【死锁检测】等手段
预防死锁发生。但是如果一旦发生了死锁就没法解开了,只能停掉程序,修复bug后再启动服务了。^_^ 如有不当之处,欢迎指正
^_^ 参考链接
https://www.cnblogs.com/kongzhongqijing/articles/3630264.html
https://www.jianshu.com/p/6690f7e92f27
https://mp.weixin...^_^ 本文已经被收录进《程序员成长笔记(四)》,笔者JustryDeng
-
-
JSTACK
2020-06-15 23:55:50JSTACK 再jvm调优或者说再解决一些java线程方面的问题时候需要用到的一个工具JSTACK,他可以看到目前正在运行的java程序的栈状态。对于栈我们知道。其实就是栈帧的调用顺序和里面的指令。 JSTACK的命令格式 jstack ...JSTACK
再jvm调优或者说再解决一些java线程方面的问题时候需要用到的一个工具JSTACK,他可以看到目前正在运行的java程序的栈状态。对于栈我们知道。其实就是栈帧的调用顺序和里面的指令。
JSTACK的命令格式
jstack [ option ] pid
jstack [ option ] executable core
jstack [ option ] [server-id@]remote-hostname-or-IP最最最最常用的就是jstack pid 【进程号】。
JSTACK 的关注点
jstack 出来的dump中包含所有现在这个进程中正在运行的所有线程堆栈信息。还有线程的当前状态【需要主要关注的是waiting 状态以及 blocked状态】。以及栈帧的运行指令行数【其实就是代码对应的类名称以及行号】。
举例一个死锁的问题
当jstack 命令执行完成后
看到很多线程的都是waiting的状态,而后面跟着某块内存地址【<0X0000…>】 这种类似的,再waitting状态中的线程后跟着的都是相同值的内存地址,说明目前程序有很多限制再waiting同一对象,为了等待获取同一把锁资源。针对大量相同的地址需要进行反查找,查看哪一个线程获取的锁资源状态是runnable状态,而且锁资源与前相同,说明当前线程占用用次对象资源没有释放,从而导致了其他线程的waiting状态。JINFO
这个jinfo pid 这个命令其实就是查看你当前进程的一些相关信息,运行环境信息,jvm设置,配置参数等等这些东西。
一般都是别人启动的java命令。你通过jinfo可以看到 这个java进程的运行或者启动的信息JMAP
使用办法
jmap -histor {pid} | head -20 列出前20个 占用内存最多的对象 -
Jstack
2021-01-07 14:21:32Jstack jstack命令的语法格式: jstack 。可以用jps查看java进程id。这里要注意的是: \1. 不同的 JAVA虚机的线程 DUMP的创建方法和文件格式是不一样的,不同的 JVM版本, dump信息也有差别。 \2. 在实际运行中,...Jstack
jstack命令的语法格式: jstack 。可以用jps查看java进程id。这里要注意的是:
\1. 不同的 JAVA虚机的线程 DUMP的创建方法和文件格式是不一样的,不同的 JVM版本, dump信息也有差别。
\2. 在实际运行中,往往一次 dump的信息,还不足以确认问题。建议产生三次 dump信息,如果每次 dump都指向同一个问题,我们才确定问题的典型性。
jstack Dump 日志文件中的线程状态
dump 线程状态
死锁, Deadlock(重点关注)
执行中,Runnable
等待资源, Waiting on condition(重点关注)
等待获取监视器, Waiting on monitor entry(重点关注)
暂停,Suspended
对象等待中,Object.wait() 或 TIMED_WAITING
阻塞, Blocked(重点关注)
停止,Parked
线程状态含义
Deadlock:死锁线程,一般指多个线程调用间,进入相互资源占用,导致一直等待无法释放的情况。
Runnable:一般指该线程正在执行状态中,该线程占用了资源,正在处理某个请求,有可能正在传递SQL到数据库执行,有可能在对某个文件操作,有可能进行数据类型等转换。
Waiting on condition:该状态出现在线程等待某个条件的发生。具体是什么原因,可以结合 stacktrace来分析。最常见的情况是线程在等待网络的读写,比如当网络数据没有准备好读时,线程处于这种等待状态,而一旦有数据准备好读之后,线程会重新激活,读取并处理数据。在 Java引入 NewIO之前,对于每个网络连接,都有一个对应的线程来处理网络的读写操作,即使没有可读写的数据,线程仍然阻塞在读写操作上,这样有可能造成资源浪费,而且给操作系统的线程调度也带来压力。在 NewIO里采用了新的机制,编写的服务器程序的性能和可扩展性都得到提高。
如果发现有大量的线程都在处在 Wait on condition,从线程 stack看, 正等待网络读写,这可能是一个网络瓶颈的征兆。因为网络阻塞导致线程无法执行。一种情况是网络非常忙,几 乎消耗了所有的带宽,仍然有大量数据等待网络读 写;另一种情况也可能是网络空闲,但由于路由等问题,导致包无法正常的到达。所以要结合系统的一些性能观察工具来综合分析,比如 netstat统计单位时间的发送包的数目,如果很明显超过了所在网络带宽的限制 ; 观察 cpu的利用率,如果系统态的 CPU时间,相对于用户态的 CPU时间比例较高;如果程序运行在 Solaris 10平台上,可以用 dtrace工具看系统调用的情况,如果观察到 read/write的系统调用的次数或者运行时间遥遥领先;这些都指向由于网络带宽所限导致的网络瓶颈。另外一种出现 Wait on condition的常见情况是该线程在 sleep,等待 sleep的时间到了时候,将被唤醒。
locked:线程阻塞,是指当前线程执行过程中,所需要的资源长时间等待却一直未能获取到,被容器的线程管理器标识为阻塞状态,可以理解为等待资源超时的线程。
Waiting for monitor entry 和 in Object.wait():Monitor是 Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁。每一个对象都有,也仅有一个 monitor。
C:\Users\srqnk>jstack 8064 2020-07-30 11:25:22 Full thread dump Java HotSpot(TM) Client VM (25.131-b11 mixed mode): "DestroyJavaVM" #10 prio=5 os_prio=0 tid=0x00f5cc00 nid=0x1edc waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE "Thread-1" #9 prio=5 os_prio=0 tid=0x15360400 nid=0x280c waiting for monitor entry [0x159cf000] java.lang.Thread.State: BLOCKED (on object monitor) at com.agree.Exam.ThreadRunB.run(DiedsynchronizedTest.java:42) - waiting to lock <0x04ee2840> (a java.lang.Integer) - locked <0x04ef8920> (a java.lang.Integer) "Thread-0" #8 prio=5 os_prio=0 tid=0x1535fc00 nid=0x3968 waiting for monitor entry [0x1593f000] java.lang.Thread.State: BLOCKED (on object monitor) at com.agree.Exam.ThreadRunA.run(DiedsynchronizedTest.java:21) - waiting to lock <0x04ef8920> (a java.lang.Integer) - locked <0x04ee2840> (a java.lang.Integer) "Service Thread" #7 daemon prio=9 os_prio=0 tid=0x152f2800 nid=0x524 runnable [0x00000000] java.lang.Thread.State: RUNNABLE "C1 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x152c4000 nid=0x960 waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE "Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x15298000 nid=0x2fe4 waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE "Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x152c3000 nid=0x1e3c runnable [0x00000000] java.lang.Thread.State: RUNNABLE "Finalizer" #3 daemon prio=8 os_prio=1 tid=0x1527a400 nid=0x2718 in Object.wait() [0x1557f000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x04e07ee0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) - locked <0x04e07ee0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209) "Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x15264400 nid=0x2630 in Object.wait() [0x154ef000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x04e05f68> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference.tryHandlePending(Reference.java:191) - locked <0x04e05f68> (a java.lang.ref.Reference$Lock) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153) "VM Thread" os_prio=2 tid=0x02c6dc00 nid=0xcb4 runnable "VM Periodic Task Thread" os_prio=2 tid=0x1533b800 nid=0x5c4 waiting on condition JNI global references: 6 Found one Java-level deadlock: ============================= "Thread-1": waiting to lock monitor 0x15268f14 (object 0x04ee2840, a java.lang.Integer), which is held by "Thread-0" "Thread-0": waiting to lock monitor 0x15267624 (object 0x04ef8920, a java.lang.Integer), which is held by "Thread-1" Java stack information for the threads listed above: =================================================== "Thread-1": at com.agree.Exam.ThreadRunB.run(DiedsynchronizedTest.java:42) - waiting to lock <0x04ee2840> (a java.lang.Integer) - locked <0x04ef8920> (a java.lang.Integer) "Thread-0": at com.agree.Exam.ThreadRunA.run(DiedsynchronizedTest.java:21) - waiting to lock <0x04ef8920> (a java.lang.Integer) - locked <0x04ee2840> (a java.lang.Integer) Found 1 deadlock.
"Thread-1" #9 prio=5 os_prio=0 tid=0x15360400 nid=0x280c waiting for monitor entry [0x159cf000]
“Thread-1”:线程名称
#9:线程编号
prio:线程的优先级别
os_prio:系统级别的线程优先级
tid:线程id
nid:native线程id
waiting for monitor entry [0x159cf000]:线程当前状态
进程区域的划分
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-grOSvspV-1610000415287)(C:\Users\srqnk\AppData\Roaming\Typora\typora-user-images\1596095856121.png)]
先级
tid:线程id
nid:native线程id
waiting for monitor entry [0x159cf000]:线程当前状态
进程区域的划分
[外链图片转存中…(img-grOSvspV-1610000415287)]
重量级锁也就是通常说synchronized的对象锁,锁标识位为10,其中指针指向的是monitor对象(也称为管程或监视器锁)的起始地址。每个对象都存在着一个 monitor 与之关联,对象与其 monitor 之间的关系有存在多种实现方式,如monitor可以与对象一起创建销毁或当线程试图获取对象锁时自动生成,但当一个 monitor 被某个线程持有后,它便处于锁定状态。
-
jstack工具
2021-01-29 17:03:051.jstack介绍: jstack用于生成java虚拟机当前时刻的线程快照。 线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、...jstack介绍:
jstack用于生成java虚拟机当前时刻的线程快照。
线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。
线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。
在dump文件里,值得关注的线程状态有:
- 死锁,Deadlock(重点关注) 。
- 执行中,Runnable。
- 等待资源,Waiting on condition(重点关注)。
- 等待获取监视器,Waiting on monitor entry(重点关注)。
- 暂停,Suspended。
- 对象等待中,Object.wait() 或 TIMED_WAITING。
- 阻塞,Blocked(重点关注)。
- 停止,Parked。
命令格式
打印进程线程转储命令: jstack -l PID > /data/dump/jstack.txt
dump格式
"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f7b54101800 nid=0x69d0 in Object.wait() [0x00007f7b4416c000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000f5cd91e0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x00000000f5cd91e0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)Locked ownable synchronizers:
- None值 含义 Finalizer 线程名称 prio=8 线程的优先级,数字从1到10,其中1为最低,10为最高优先级 tid=0x00007f7b54101800 线程ID nid=0x69d0 本地硬件线程id Object.wait() 线程状态,此状态为对象等待中
-
jstack命令使用jstack日志查看
2021-02-05 11:12:33jstack是java虚拟机自带的一种堆栈跟踪工具。 jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的... -
jstack 命令
2019-09-21 14:10:40NAME jstack - Prints Java thread stack traces for a Java process, core file, or remote debug server. SYNOPSIS jstack [ options ] pid jstack [ options ] executable c... -
jstack使用
2018-07-05 21:24:00jstack使用 jvm jstack工具 jstack简介 jstack能得到运行java程序的java stack 和native stack的信息,可以轻松得知当前线程的运行情况。 用法 jstack [ option ] pid jstack [ option ] executable... -
jvm性能调优工具 jstack
2020-09-07 10:03:18jdk1.8 jstack jstack是jdk自带的线程堆栈分析工具,使用该命令可以查看线程id,线程状态,是否持有锁。或导出java应用程序中线程堆栈信息。 -
jstack介绍
2019-09-29 18:25:52jstack用于打印出给定的java进程ID或corefile或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使用方式只支持以下的这种方式: jstack[-l]pid 如果java程序崩溃生成core... -
jstack命令
2019-04-23 16:55:04jstack是java虚拟机自带的一种堆栈跟踪工具。jstack用于打印出给定的java进程ID或corefile或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使用方式只支持以下的这种方式... -
linux 使用jstack_jstack的使用
2020-12-20 14:47:15jstack简介通过jstack,我们可以轻松得知jvm中各个线程的工作情况.工作情况jstack -l pid (查出某个进程中运行的所有线程)利用ps -aux 找出我们的java线程41,然后再用jstack -l 41,就可以查看jvm此刻运行的所有线程....
-
安卓程序开发多开!啃完999页Android面试高频宝典,我先收藏为敬
-
安卓10
-
虚幻4引擎基础
-
基于摄像法测量弹丸的空间炸点位置
-
歌声合成从入门到精通
-
龙芯实训平台应用实战(希云)
-
access应用的3个开发实例
-
基于聚类分析算法的数字化图书馆、图书馆管理系统
-
使用Python一步一步地来进行数据分析总结
-
FPS游戏逆向-UE4虚幻四游戏逆向
-
龙芯生态应用开发基础:C语言精要
-
普吉岛常玩海滩景点游玩活动总攻略转 - 副本.docx
-
基于渐变折射率多模光纤的光纤干涉折射率传感器的空分复用
-
RapidScada从入门到精通
-
广义回归神经网络的改进及在交通预测中的应用
-
Superbee编译服务器及虚拟机环境搭建
-
TOGAF考试报名流程.pdf
-
Linux基础入门系列课程
-
跨测量系统的多天空屏幕中的分析和计算对象检测捕获率
-
服务器