怎样使用jstack诊断Java应用程序故障(转)
最近一段时间,我们的生产系统升级频繁出现故障,具体故障现象是启动后10来分钟就出现交易缓慢,处理线程耗尽等现象,并且故障发生的频率蛮高的。经过详细的诊断和排查,终于发现了问题,是groovy在osgi中运行会出现classloader死锁,最后我们也解决了这个问题。
如果单靠通过查看代码是很难去发现这个问题,在这一次故障排查中,我也学到了怎样更好的使用jvm监控工具来进行诊断,主要用到了jstack和jmap命令,jmap上次已经讲过就不再讲了,下面就一个例子来讲怎么使用jstack来对的Java程序进行诊断。
首先让我们来了解一下jstack这个命令的作用,jstack 是一个可以返回在应用程序上运行的各种各样线程的一个完整转储的实用程序,您可以使用它查明问题。jstack [-l] <pid>,jpid可以通过使用jps命令来查看当前Java程序的jpid值,-l是可选参数,它可以显示线程阻塞/死锁情况。
/**
* 死锁例子
*/
public class DeadLock { public static void main(String[] args) {
final Object obj_1 = new Object(), obj_2 = new Object(); Thread t1 = new Thread("t1"){
@Override
public void run() {
synchronized (obj_1) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {} synchronized (obj_2) {
System.out.println("thread t1 done.");
}
}
}
}; Thread t2 = new Thread("t2"){
@Override
public void run() {
synchronized (obj_2) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {} synchronized (obj_1) {
System.out.println("thread t2 done.");
}
}
}
}; t1.start();
t2.start();
} }
以上DeadLock类是一个死锁的例子,假使在我们不知情的情况下,运行DeadLock后,发现等了N久都没有在屏幕打印线程完成信息。这个时候我们就可以使用jps查看该程序的jpid值和使用jstack来生产堆栈结果问题。
$ java -cp deadlock.jar DeadLock &
$
$ jps
Jps
DeadLock
$ jstack -l > deadlock.jstack
结果文件deadlock.jstack内容如下:
2011-03-20 23:05:20
Full thread dump Java HotSpot(TM) Client VM (19.1-b02 mixed mode, sharing): "DestroyJavaVM" prio=6 tid=0x00316800 nid=0x9fc waiting on condition [0x00000000]
java.lang.Thread.State: RUNNABLE Locked ownable synchronizers:
- None "t2" prio=6 tid=0x02bcf000 nid=0xc70 waiting for monitor entry [0x02f6f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.demo.DeadLock$2.run(DeadLock.java:40)
- waiting to lock <0x22a297a8> (a java.lang.Object)
- locked <0x22a297b0> (a java.lang.Object) Locked ownable synchronizers:
- None "t1" prio=6 tid=0x02bce400 nid=0xba0 waiting for monitor entry [0x02f1f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.demo.DeadLock$1.run(DeadLock.java:25)
- waiting to lock <0x22a297b0> (a java.lang.Object)
- locked <0x22a297a8> (a java.lang.Object) Locked ownable synchronizers:
- None "Low Memory Detector" daemon prio=6 tid=0x02bb9400 nid=0xa6c runnable [0x00000000]
java.lang.Thread.State: RUNNABLE Locked ownable synchronizers:
- None "CompilerThread0" daemon prio=10 tid=0x02bb2800 nid=0xcb8 waiting on condition [0x00000000]
java.lang.Thread.State: RUNNABLE Locked ownable synchronizers:
- None "Attach Listener" daemon prio=10 tid=0x02bb1000 nid=0x7f4 waiting on condition [0x00000000]
java.lang.Thread.State: RUNNABLE Locked ownable synchronizers:
- None "Signal Dispatcher" daemon prio=10 tid=0x02bd2800 nid=0xd80 runnable [0x00000000]
java.lang.Thread.State: RUNNABLE Locked ownable synchronizers:
- None "Finalizer" daemon prio=8 tid=0x02bab000 nid=0xe1c in Object.wait() [0x02d3f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x229e1148> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
- locked <0x229e1148> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159) Locked ownable synchronizers:
- None "Reference Handler" daemon prio=10 tid=0x02ba6800 nid=0xbe0 in Object.wait() [0x02cef000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x229e1048> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
- locked <0x229e1048> (a java.lang.ref.Reference$Lock) Locked ownable synchronizers:
- None "VM Thread" prio=10 tid=0x02b6a400 nid=0x568 runnable "VM Periodic Task Thread" prio=10 tid=0x02bc8400 nid=0x75c waiting on condition JNI global references: 878 Found one Java-level deadlock:
=============================
"t2":
waiting to lock monitor 0x02baaeec (object 0x22a297a8, a java.lang.Object),
which is held by "t1"
"t1":
waiting to lock monitor 0x02baa2bc (object 0x22a297b0, a java.lang.Object),
which is held by "t2" Java stack information for the threads listed above:
===================================================
"t2":
at com.demo.DeadLock$2.run(DeadLock.java:40)
- waiting to lock <0x22a297a8> (a java.lang.Object)
- locked <0x22a297b0> (a java.lang.Object)
"t1":
at com.demo.DeadLock$1.run(DeadLock.java:25)
- waiting to lock <0x22a297b0> (a java.lang.Object)
- locked <0x22a297a8> (a java.lang.Object) Found 1 deadlock.
从这个结果文件我们一看到发现了一个死锁,具体是线程t2在等待线程t1,而线程t1在等待线程t2造成的,同时也记录了线程的堆栈和代码行数,通过这个堆栈和行数我们就可以去检查对应的代码块,从而发现问题和解决问题。
http://crane-ding.iteye.com/blog/968862
怎样使用jstack诊断Java应用程序故障(转)的更多相关文章
- JDK tools之jps和jstack诊断Java程序
大部分Java开发者可能知道有这么个工具,但是没怎么用过,每次还得百度一下.我也是之一 -_-!!. 每次遇到
- 使用JDK工具进行Java服务器应用程序故障排除
Java性能调优指南–有关提高Java代码性能的各种技巧. 最近又学到了很多新知识,感谢优锐课老师细致地讲解,这篇博客记录下自己所学所想. 1. 介绍 在Java世界中,我们大多数人习惯于在Java应 ...
- [刘阳Java]_Java程序员的成长路线_第3讲
按照Java从业人员的职位晋升来说,Java程序成长路线大致如下 Java程序员 JavaEE初级软件工程师 JavaEE中级软件工程师 JavaEE高级软件工程师 Java架构师 按照职业发展方向, ...
- 在Docker中监控Java应用程序的5个方法
译者注:Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化.通常情况下,监控的主要目的在于:减少宕机 ...
- 在 Linux 上创建第一个 Service Fabric Java 应用程序
先决条件 开始之前,请安装 Service Fabric SDK.Azure CLI,并在 Linux 开发环境中设置开发群集. 如果使用 Mac OS X,则可使用 Vagrant 在虚拟机中设置 ...
- 诊断Java代码中常见的数据库性能热点问题应该这么做!
“你的Java应用程序的性能是怎样诊断和优化的?不妨看看这两位西医的方子.如果你有更好疗效的药方,也欢迎在评论区告诉我们. 当我在帮助一些开发者或架构师分析及优化Java应用程序的性能时,关键往往不在 ...
- Java虚拟机性能管理神器 - VisualVM(6) 排查JAVA应用程序内存泄漏【转】
Java虚拟机性能管理神器 - VisualVM(6) 排查JAVA应用程序内存泄漏[转] 标签: javajvm内存泄漏监控工具 2015-03-11 18:30 1870人阅读 评论(0) 收藏 ...
- Java基础-输入输出-3.编写BinIoDemo.java的Java应用程序,程序完成的功能是:完成1.doc文件的复制,复制以后的文件的名称为自己的学号姓名.doc。
3.编写BinIoDemo.java的Java应用程序,程序完成的功能是:完成1.doc文件的复制,复制以后的文件的名称为自己的学号姓名.doc. try { FileInputStream in = ...
- Java基础-输入输出-2.编写IoDemo.java的Java应用程序,程序完成的功能是:首先读取text.txt文件内容,再通过键盘输入文件的名称为iodemo.txt,把text.txt的内容存入iodemo.txt
2.编写IoDemo.java的Java应用程序,程序完成的功能是:首先读取text.txt文件内容,再通过键盘输入文件的名称为iodemo.txt,把text.txt的内容存入iodemo.txt ...
随机推荐
- php 学习笔记 数组1
1.一般情况下$name['tom']和$name[tom]是相同的:但没有引号的键不能和常量区别开,如:define('index', 5)时:$name['tom']和$name[tom]不同 2 ...
- HDU 5025Saving Tang Monk BFS + 二进制枚举状态
3A的题目,第一次TLE,是因为一次BFS起点到终点状态太多爆掉了时间. 第二次WA,是因为没有枚举蛇的状态. 解体思路: 因为蛇的数目是小于5只的,那就首先枚举是否杀死每只蛇即可. 然后多次BFS, ...
- php启用gzip压缩
GZIP(GNU-ZIP)是一种压缩技术.经过GZIP压缩后页面大小可以变为原来的30%甚至更小.这样用户浏览的时候就会感觉很爽很愉快! 要实现GZIP压缩页面需要浏览器和服务器共同支持,实际上就是服 ...
- THUSC2015
这些题目在BZOJ上面有,可惜是权限题.话说BZOJ上面的题目真的挺好的,要不是我穷,早就去弄个号了! 言归正传,今年的题目难度可以由一个名人名言看出: 题目太水.--某某神犇 可是我掂量了一下,发现 ...
- C++ pair 使用方法
类模板:template <class T1, class T2> struct pair 參数:T1是第一个值的数据类型,T2是第二个值的数据类型. 功能:pair将一对值组合成一个值, ...
- Android Cocos2d-x游戏集成友盟社会化组件分享功能
最近在帮助开发者集成友盟社会化组件的过程中,发现游戏的集成过程遇到一些困难,而Cocos2d-x具有较好的代表性,因此整理了一篇关于Android Cocos2d-x游戏集成友盟社会化组件指南,由于本 ...
- Shell基础一
Shell指令: shell识别三种基本命令:内建命令.Shell函数以及外部命令: 内建命令就是由shell本身所执行的命令.有些命令是由于其必要性才内建的:例如:cd.read: 另一种内建命令的 ...
- JQuery - 改变css样式
jQuery提供css()的方法来实现嵌入式改变元素样式,css()方法在使用上具有多样性.其中一种接受两个输入参数:样式属性和样式值,它们之间用逗号分开.比如我们要改变链接颜色,我们可以使用下面的代 ...
- C# 点击窗口任意位置拖动
代码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; ...
- SQL Server 基础 01 数据库、表操作
对着书慢慢学习,一天一点点! 数据库操作 (create.alter.drop) --3-3-1 /create database 语句创建数据库 create database testSQL - ...