jstack+jdb命令查看线程及死锁堆栈信息的实例
如果程序挂死,有时使用jstack查看进程中线程信息时,需要添加上-F参数,此时如果有死锁信息,则可能不会打印出死锁堆栈信息,使用jdb则可以查看当前死锁线程的运行堆栈。
如下模拟一个简单的死锁程序
packagecom.demo.bootdemo; importjava.util.HashMap; importjava.util.Map; importorg.springframework.context.ApplicationListener; importorg.springframework.context.event.ContextRefreshedEvent; importorg.springframework.stereotype.Component; @Component publicclassMyListenersimplementsApplicationListener{ privateMapmap=newHashMap<>(); privateStringlock="aa"; @Override publicvoidonApplicationEvent(ContextRefreshedEventarg0){ Threadt=newThread(newRunnable(){ @Override publicvoidrun(){ synchronized(map){ System.out.println(Thread.currentThread().getName()+":获得map锁"); try{ Thread.sleep(1000); }catch(InterruptedExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } synchronized(lock){ System.out.println(Thread.currentThread().getName()+":获得lock锁"); } } } },"t-1"); Threadt2=newThread(newRunnable(){ @Override publicvoidrun(){ synchronized(lock){ System.out.println(Thread.currentThread().getName()+":获得lock锁"); try{ Thread.sleep(1000); }catch(InterruptedExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } synchronized(map){ System.out.println(Thread.currentThread().getName()+":获得map锁"); } } } },"t-2"); t.start(); t2.start(); } }
获取pid
假设当前不能直接连接27709虚拟机,需要使用参数-F
可以看出造成死锁的线程未t-1和t-2
使用jdb连接jvm
jdb-connectsun.jvm.hotspot.jdi.SAPIDAttachingConnector:pid=27709
执行threads命令获取所有线程列表
获取线程“t-1”堆栈信息,如下图,结合上述模拟死锁的代码,很容易就能看出来是哪里的问题
类似的,获取线程“t-2”的堆栈信息
通过以上步骤,基本上可以确定问题代码了。
本例也是匆忙中简单查看了下文档,没有详看,后续有时间在进行补充,jdb文档如下
https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr011.html#BABDHAHJ
补充:java性能监控jstack线程死锁JConsole和BTrace图形化工具
java性能监控工具
除了javacjavajavap之外,jdk安装包还提供了很多其他工具
列出bin目录下的文件
TomChens-MacBook-Pro:Commandstomchen$ls appletviewerjavadocjmapkeytoolserialver aptjavahjmcnative2asciiservertool extcheckjavapjpsorbdtnameserv idljjavawsjrunscriptpack200unpack200 jarjcmdjsadebugdpolicytoolwsgen jarsignerjconsolejstackrmicwsimport javajdbjstatrmidxjc java_homejhatjstatdrmiregistry javacjinfojvisualvmschemagen
jvisualvm
可以在线安装很多插件,这是最新的非常强大的多合一故障处理工具
生成HeapDump,可以在OQLConsole执行类似sql语句的OQL
jvisualvm的BTrace插件
生产环境服务无法停止的时候,而日志里的信息无法满足我们需要时候,可以通过这个打印调用堆栈参数返回值等
jconsole
也是一个图形化的监控工具
jps虚拟机进程状况工具
类似于ps命令
jps-l 582HttpFind 431RefreshBlog.jar 585sun.tools.jps.Jps
jstat虚拟机统计信息监控工具
jstat-gcutil431 S0S1EOPYGCYGCTFGCFGCTGCT 0.0057.1712.4324.7442.31130.04400.0000.044
从中可以看出survivor(S0S1)eden(E)youngGC(YGC)等参数
jstat-class434 LoadedBytesUnloadedBytesTime 1709536897.718992970.914.87
类加载时间为14.87
jstackjava堆栈管理工具
可以查看线程死锁
jstack582 ...... ...... FoundoneJava-leveldeadlock: ============================= "Thread-199": waitingtolockmonitor0x00007facb3027608(object0x00000007e786b528,ajava.lang.Integer), whichisheldby"Thread-3" "Thread-3": waitingtolockmonitor0x00007facb3026108(object0x00000007e786b518,ajava.lang.Integer), whichisheldby"Thread-8" "Thread-8": waitingtolockmonitor0x00007facb3027608(object0x00000007e786b528,ajava.lang.Integer), whichisheldby"Thread-3" Javastackinformationforthethreadslistedabove: =================================================== "Thread-199": atHttpFind$SyncAdd.run(HttpFind.java:52) -waitingtolock<0x00000007e786b528>(ajava.lang.Integer) atjava.lang.Thread.run(Thread.java:722) "Thread-3": atHttpFind$SyncAdd.run(HttpFind.java:53) -waitingtolock<0x00000007e786b518>(ajava.lang.Integer) -locked<0x00000007e786b528>(ajava.lang.Integer) atjava.lang.Thread.run(Thread.java:722) "Thread-8": atHttpFind$SyncAdd.run(HttpFind.java:53) -waitingtolock<0x00000007e786b528>(ajava.lang.Integer) -locked<0x00000007e786b518>(ajava.lang.Integer) atjava.lang.Thread.run(Thread.java:722) Found1deadlock.
jhat虚拟机堆转储快照分析工具
jinfojava配置信息工具
jmapjava内存印象工具
以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。