dump 文件里,值得关注的线程状态有:
  1. 死锁,Deadlock(重点关注) 
  2. 执行中,Runnable
  3. 等待资源,Waiting on condition(重点关注)
  4. 等待获取监视器,Waiting on monitor entry(重点关注)
  5. 暂停,Suspended
  6. 对象等待中,Object.wait() 或 TIMED_WAITING
  7. 阻塞,Blocked(重点关注)  
  8. 停止,Parked

Runnable:不解释

Blocked:线程阻塞,是指当前线程执行过程中,所需要的资源长时间等待却一直未能获取到,被容器的线程管理器标识为阻塞状态,可以理解为等待资源超时的线程

Wait on condition:该状态出现在线程等待某个条件的发生。具体是什么原因,可以结合 stacktrace来分析。最常见的情况是线程在等待网络的读写。如果网络数据没准备好,线程就等待在那里。另外一种出现 Wait on condition的常见情况是该线程在 sleep,等待 sleep的时间到了时候,将被唤醒。

Waiting for monitor entry 和 in Object.wait():这两种情况在多线程的情况下经常出现。Java是通过Monitor来实现线程互斥和协作(有些把Monitor直译成锁,我认为不妥,不是还有Lock嘛)。具体Monitor的深入理解见 http://www.cnblogs.com/tomsheep/archive/2010/06/09/1754419.html

但是可以理解成Monitor是一个对象或者class所拥有的锁,每个对象和class有且仅有一个。见下图.

每个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 “Active Thread”,而其它线程都是 “Waiting Thread”,分别在两个队列 “ Entry Set”和 “Wait Set”里面等候。

在 “ Entry Set”里面的线程都等待拿到Monitor,拿到了线程就成为了Runnable线程,否则就会一直处于处于 “waiting for monitor entry”。一段代码作为例子

public class MyThread implements Runnable{    public void run() {    synchronized(this) {    for (int i = 0; i < 1; i--) {    System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);    }    }    }    public static void main(String[] args) {    MyThread t1 = new MyThread();    Thread ta = new Thread(t1, "A");    Thread tb = new Thread(t1, "B");    ta.start();    tb.start();    }   }  

大家一看就知道,B线程肯定是“千年老二“,永远拿不到Monitor了。

对应的stack:

"B" prio=10 tid=0x0969a000 nid=0x11d6 waiting for monitor entry [0x8bb22000]  java.lang.Thread.State: BLOCKED (on object monitor)  at org.marshal.MyThread.run(MyThread.java:7)  - waiting to lock <0x94757078> (a org.marshal.MyThread)  at java.lang.Thread.run(Thread.java:636)  "A" prio=10 tid=0x09698800 nid=0x11d5 runnable [0x8bb73000]  java.lang.Thread.State: RUNNABLE  at java.io.FileOutputStream.writeBytes(Native Method)  at java.io.FileOutputStream.write(FileOutputStream.java:297)  at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)  at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)  - locked <0x947571b0> (a java.io.BufferedOutputStream)  at java.io.PrintStream.write(PrintStream.java:449)  - locked <0x94757190> (a java.io.PrintStream)  at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:220)  at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:290)  at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:103)  - locked <0x947572a0> (a java.io.OutputStreamWriter)  at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)  at java.io.PrintStream.write(PrintStream.java:494)  - locked <0x94757190> (a java.io.PrintStream)  at java.io.PrintStream.print(PrintStream.java:636)  at java.io.PrintStream.println(PrintStream.java:773)  - locked <0x94757190> (a java.io.PrintStream)  at org.marshal.MyThread.run(MyThread.java:8)  - locked <0x94757078> (a org.marshal.MyThread)  at java.lang.Thread.run(Thread.java:636)  

<0x94757078> 就是两个线程争夺的Monitor

在 “Wait Set”里面的线程都如饥似渴地等待拿到Monitor。他们是怎么进入到“Wait Set”的呢?当一个线程拿到了Monitor,但是在其他资源没有到位的情况下,调用同步锁对象(一般是synchronized()内的对象)的 wait() 方法,放弃了 Monitor,它就进入到了 “Wait Set”队列。只有当其他线程通过notify() 或者 notifyAll(),释放了同步锁后,这个线程才会有机会重新去竞争Monitor。在stack中,它表现的状态是in Object.wait()。修改上面的代码public class WaitThread implements Runnable{

public void run() {    synchronized(this) {   try {  this.wait();  } catch (InterruptedException e) {  // TODO Auto-generated catch block
        e.printStackTrace();  }              }    }    public static void main(String[] args) {    WaitThread t1 = new WaitThread();    Thread ta = new Thread(t1, "A");    Thread tb = new Thread(t1, "B");    ta.start();    tb.start();            }   

对应的stack:

"B" prio=10 tid=0x08173000 nid=0x1304 in Object.wait() [0x8baf2000]  java.lang.Thread.State: WAITING (on object monitor)  at java.lang.Object.wait(Native Method)  - waiting on <0xa9cb50e0> (a org.marshal.WaitThread)  at java.lang.Object.wait(Object.java:502)  at org.marshal.WaitThread.run(WaitThread.java:8)  - locked <0xa9cb50e0> (a org.marshal.WaitThread)  at java.lang.Thread.run(Thread.java:636)  "A" prio=10 tid=0x08171c00 nid=0x1303 in Object.wait() [0x8bb43000]  java.lang.Thread.State: WAITING (on object monitor)  at java.lang.Object.wait(Native Method)  - waiting on <0xa9cb50e0> (a org.marshal.WaitThread)  at java.lang.Object.wait(Object.java:502)  at org.marshal.WaitThread.run(WaitThread.java:8)  - locked <0xa9cb50e0> (a org.marshal.WaitThread)  at java.lang.Thread.run(Thread.java:636)  

A和B线程都进入了”wait set“。B线程也拿到过这个Monitor,因为A线程释放过了,这也验证上面的话,他们都在等待得而复失的<0xa9cb50e0>

 热锁

热锁,也往往是导致系统性能瓶颈的主要因素。其表现特征为,由于多个线程对临界区,或者锁的竞争,可能出现:
    * 频繁的线程的上下文切换:从操作系统对线程的调度来看,当 线程在等待资源而阻塞的时候,操作系统会将之切换出来,放到等待的队列,当线程获得资源之后,调度算法会将这个线程切换进去,放到执行队列中。
    * 大量的系统调用:因为线程的上下文切换,以及热锁的竞争,或 者临界区的频繁的进出,都可能导致大量的系统调用。
    * 大部分 CPU开销用在 “系统态 ”:线程上下文切换,和系统调用,都会导致 CPU在 “系统态 ”运行,换而言之,虽然系统很忙碌,但是 CPU用在 “用户态 ”的比例较小,应用程序得不到充分的 CPU资源。 

    * 随着 CPU数目的增多,系统的性能反而下降。因为 CPU数目多,同 时运行的线程就越多,可能就会造成更频繁的线程上下文切换和系统态的 CPU开销,从而导致更糟糕的性能。 
上面的描述,都是一个 scalability(可扩展性)很差的系统的表现。从整体的性能指标看,由于线程热锁的存在,程序的响应时间会变长,吞吐量会降低。< /span>
         那么,怎么去了解 “热锁 ”出现在什么地方呢?一个重要的方法还是结合操作系统的各种工具观察系统资源使用状况,以及收集 Java线程的 DUMP信息,看线程都阻塞在什么方法上,了解原因,才能找到对应的解决方法。
        我们曾经遇到过这样的例子,程序运行时,出现了以上指出的各种现象,通过观察操作系统的资源使用统计信息,以及线程 DUMP信息,确定了程序中热锁的存在,并发现大多数的线程状态都是 Waiting for monitor entry或者 Wait on monitor,且是阻塞在压缩和解压缩的方法上。后来采用第三方的压缩包 javalib替代 JDK自带的压缩包后,系统的性能提高了几倍

转自  http://go-on.iteye.com/blog/1673894

http://www.cnblogs.com/zhengyun_ustc/archive/2013/01/06/dumpanalysis.html

   http://jameswxx.iteye.com/blog/1041173

转载于:https://www.cnblogs.com/SamuelSun/p/5660574.html

jstack 使用(转)相关推荐

  1. JDK源码研究Jstack,JMap,threaddump,dumpheap的原理

    JDK最新bug和任务领取:https://bugs.openjdk.java.net/projects/JDK/issues 参加OpenJDK社区:https://bugs.openjdk.jav ...

  2. jvm调优工具_JVM性能调优监控工具jps、jstack、jmap、jhat、hprof使用详解

    来自:ITeye博客, 作者:Josh_Persistence 链接:https://www.iteye.com/blog/josh-persistence-2161848 现实企业级Java应用开发 ...

  3. java 分析jstack日志_望闻问切使用jstack和jmap剖析java进程各种疑难杂症

    最近碰到多起java程序导致服务器cpu使用率100%的情况,下面把排查解决方法记录下来. 其实遇到这种情况,首先要保持冷静的头脑,遇事不乱.然后望闻问切,找到病根,直达病灶.所谓望闻问切就是,首先使 ...

  4. 将线程pid转成16进制_如何使用jstack分析线程状态

    背景 记得前段时间,同事说他们测试环境的服务器cpu使用率一直处于100%,本地又没有什么接口调用,为什么会这样?cpu使用率居高不下,自然是有某些线程一直占用着cpu资源,那又如何查看占用cpu较高 ...

  5. java jstack dump 线程 介绍 解释

    最近抽时间把JVM运行过程中产生的一些线程进行了整理,主要是围绕着我们系统jstack生成的文件为参照依据.  前段时间因为系统代码问题,造成性能到了天花板,于是就dump了一份stack出来进行分析 ...

  6. jstack和线程dump分析

    一:jstack jstack命令的语法格式: jstack  <pid>.可以用jps查看java进程id.这里要注意的是:       1. 不同的 JAVA虚机的线程 DUMP的创建 ...

  7. jstack可以定位到线程堆栈

    java命令--jstack 工具 JVM调优之jstack找出最耗cpu的线程并定位代码 jstack可以定位到线程堆栈,根据堆栈信息我们 转载于:https://www.cnblogs.com/j ...

  8. jvm系列(四):jvm调优-命令大全(jps jstat jmap jhat jstack jinfo)

    2019独角兽企业重金招聘Python工程师标准>>> 文章同步发布于github博客地址,阅读效果更佳,欢迎品尝 运用jvm自带的命令可以方便的在生产监控和打印堆栈的日志信息帮忙我 ...

  9. 使用jstack 发现死锁

    参考:http://blog.chinaunix.net/uid-20104447-id-4075333.html 1. 据java的sdk说明,当调用一个线程的stop时(暂时不管该不该使用该方法) ...

  10. jstack分析cpu占用100%

    问题:使用jstack来分析cpu占用100%. 过程分析: 1. 运行测试程序后,top命令发现某个进程(pid)占用cpu达到100%. 2. 查看哪个线程占用最多资源: ps mp 24018 ...

最新文章

  1. 1.6 Java数组也是一种数据类型
  2. linux c截断文件
  3. python 32的值_示例解读 Python 2 和 Python 3 之间的主要差异
  4. 90后程序员代码漏洞更多?
  5. JavaEE实战班第十四天
  6. listWdiget控件
  7. Java基础---基础加强---增强for循环、自动拆装箱及享元、枚举的作用、实现带有构造方法、透彻分析反射的基础_Class类、成员变量的反射、数组参数的成员方法进行反射、数组的反射应用
  8. SystemExit: 2
  9. 最大连续区间和算法详解+代码
  10. 清风老师数学建模视频课程第1讲层次分析法
  11. V部落博客管理平台开源啦! Vue+SpringBoot强强联合!
  12. python依赖库是什么_【转】python导出依赖库
  13. sbit在c语言中作用,sbit在单片机中的表示和作用?
  14. 华为手机在计算机里怎么隐藏游戏,原来华为手机隐藏着这么多实用功能!玩一年恐怕也发现不了...
  15. 和菜鸟一起学android4.0.3源码之USB wifi移植心得
  16. java输出语句的封装
  17. 面试中有关接口测试和接口自动化的那些事 ~
  18. 百题突击12:1,SVM算法的优缺点 2,SVM的超参数C如何调节 3,SVM的核函数如何选择 4,简述SVM硬间隔推导过程 5,简述SVM软间隔推导过程
  19. NPN三极管电平反向电路
  20. 手把手教小白制作情侣天气推送号 【只需四步】

热门文章

  1. 链客区块链技术问答社区
  2. 区块链技术未来可能用于哪些方面?
  3. 行走在区块链上的智能合约
  4. vue css 应用变量_如何使用CSS Grid和CSS变量快速为应用创建原型
  5. 今日头条反爬措施形同虚设,论多平台协同在安全方面的重要性
  6. 线性回归预测PM2.5值
  7. hung-yi lee_p13_反向传播
  8. 现在参加软件测试培训就业难度大不大?
  9. Python未来的发展趋势怎么样
  10. 驱动07.USB驱动程序