当应用程序运行变慢或者发生故障时,可能通过分析java的Thread Dumps得到分析他们得到阻塞和存在瓶颈的线程。

线程堆栈是虚拟机中线程(包括锁)状态的一个瞬间状态的快照,即系统在某一个时刻所有线程的运行状态,包括每一个线程的调用堆栈,锁的持有情况。主要包含的信息包括

1、线程名字,id,线程的数量等。

2、线程的运行状态,锁的状态(锁被哪个线程持有,哪个线程在等待锁等)

3、调用堆栈包含完整的类名,所执行的方法,源代码的行数等

线程栈是瞬时快照包含线程状态以及调用关系,可以借助堆栈信息帮助分析很多性能问题。线程栈是瞬时记录,所以没有历史消息的回溯,经常需要打印几次做对比分析,并且在一般情况下都需要结合应用程序的日志进行问题定信。

1、系统cpu过高
2、性能瓶颈:如响应时间长但CPU资源并不高
3、系统运行越来越慢,响应时间长
4、系统挂起,长时间无响应或响应时间长
5、线程死锁,死循环等
6、由于线程数量太多导致的内存溢出(如无法创建线程等)

Java线程原理

线程同步

多条线程之间可以同时执行,为了确保多线程在使用共享资源上面的通用性,使用线程同步保证在同一时间只能有一条线程可以访问共享资源。

线程同步在Java中可以使用监视器。每个Java对象都有一个监视器,这个监视器只能被一个线程拥有。当一个线程要获得另外线程拥有的监视器时,需要进入等待队列直到线程释放监视器。

线程的状态

为了分析Thread Dump ,需要先了解线程的状态。线程的状态是在java.lang.Thread.State中。

1. 新建状态(New) 新创建了一个线程对象。

2. 就绪状态(Runnable) 线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。

3. 运行状态(Running) 就绪状态的线程获取了CPU,执行程序代码。

4. 阻塞状态(Blocked) 阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:

  • 等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
  • 同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
  • 其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

5. 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

Jstack使用的关键字描述的线程状态与上边线程不太一样,所以可能理解上可能会出现混淆。虽然Java中的线程一样有上述中描述的5种状态,但在实际情况下线程新建状态和死亡状态持续很短,我们也并不太关心。大多时候我们关注的是运行状态/阻塞状态,

详细过程可参考:

  • 当执行new Thread(Runnabler)后,新创建出来的线程处于new状态,这种线程不可能执行
  • 当执行thread.start()后,线程处于runnable状态,这种情况下只要得到CPU,就可以开始执行了。runnable状态的线程,会接受JVM的调度,进入running状态,但是具体何时会进入这个状态,是随机不可知的
  • running状态中的线程最为复杂,可能会进入runnable、waiting、timed_waiting、blocked、dead状态:
    • 如果CPU调度给了别的线程,或者执行了Thread.yield()方法,则进入runnable状态,但是也有可能立刻又进入running状态
    • 如果执行了Thread.sleep(long),或者thread.join(long),或者在锁对象上调用object.wait(long)方法,则会进入timed_waiting状态
    • 如果执行了thread.join(),或者在锁对象上调用了object.wait()方法,则会进入waiting状态
    • 如果进入了同步方法或者同步代码块,没有获取锁对象的话,则会进入blocked状态
    • 处于waiting状态中的线程,如果是因为thread.join()方法进入等待的,在目标thread执行完毕之后,会回到runnable状态;如果是因为object.wait()方法进入等待的话,在锁对象执行object.notify()或者object.notifyAll()之后会回到runnable状态
    • 处于timed_waiting状态中的线程,和waiting状态中的差不多,只不过是设定时间到了,就会回到runnable状态
    • 处于blocked状态中的线程,只有获取了锁之后,才会脱离阻塞状态
    • 当线程执行完毕,或者抛出了未捕获的异常之后,会进入dead状态,该线程结束

 

我们需要重点关注RUNNABLE、BLOCKED、WAITING和TIME_WAITING四种状态,jstack打印的线程堆栈中也会时时出现。

1)BLOCKED:就是线程在等待获取锁进入同步块或者同步方法中。两个死锁的线程即是Blocked。

2)WAITING:比BLOCKED状态进步一些,指已经获得锁了,但由于有些条件不满足,要自己等会,调用object.wait()方法。等条件满足了,别的线程调用notify再叫我。另外也可以调用Thread.join()方法,顾名思义就是调用别的线程的join方法,让别人join进来先执行,那我就只能等会了。但是由于wait()和notify()以及notifyAll()用于协调对共享资源的存取,所以必须在synchronized块中使用。所以即便wait状态的线程被notfiy唤醒了,也需要再次获得锁,所以唤醒后进入Blocked状态。

3)TIMED_WAITING:类比WAITING,差异是不需要notify()或者notifyAlL()方法唤醒,时间到了自己醒了。另外sleep比较好理解,就是让当前线程睡一会,与wait的区别是它不释放锁

4)RUNNABLE不用多说,在JAVA虚拟机中已经在运行,但是在等待操作系统资源,比如CPU时间片。

相关链接:

https://blog.csdn.net/rachel_luo/article/details/8920596

https://blog.csdn.net/zxp_cpinfo/article/details/54971115

线程dump的更多相关文章

  1. jstack和线程dump分析

    转自:http://jameswxx.iteye.com/blog/1041173 一:jstack jstack命令的语法格式: jstack  <pid>.可以用jps查看java进程 ...

  2. 不依赖jstack的java 线程dump和死锁检查工具

    java线程dump可以使用jdk的命令"jstack  pid"完成,死锁检查可以用jconsole查看到.这两个工具是java调试的常用方法. 我遇到的问题是:在sles11s ...

  3. [转]java线程安全、jstack\线程dump、内存查看分析总结

    http://jameswxx.iteye.com/blog/808546 java线程安全总结二 http://jameswxx.iteye.com/blog/1041173 jstack和线程du ...

  4. java线程dump分析工具

    jstack和线程dump分析  java程序性能分析之thread dump和heap dump 一.[内存dump] jmap –dump:live,format=b,file=heap.bin ...

  5. JAVA线程dump的分析

    Java 的线程 线程是指能独立于程序的其它部分运行的执行单元. JAVA语言能够很好的实现多线程的程序.我们在调试程序,或者在开发后期需要做性能调优的时候,往往也需要了解当前程序正在运行的线程的状态 ...

  6. Java中如何获取到线程dump文件

    死循环.死锁.阻塞.页面打开慢等问题,打线程dump是最好的解决问题的途径.所谓线程dump也就是线程堆栈,获取到线程堆栈有两步: (1)获取到线程的pid,可以通过使用jps命令,在Linux环境下 ...

  7. Java线程Dump分析工具--jstack【转载】

    jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使 ...

  8. Java线程Dump分析工具--jstack(转)

    jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使 ...

  9. Java线程Dump分析工具--jstack

    jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使 ...

  10. 使用jstack和TDA进行java线程dump分析

    转载:http://blog.csdn.net/everlasting_188/article/details/51943095 1.jstack重点关注 命令行:jstack [-l][F] pid ...

随机推荐

  1. Java进阶知识点8:高可扩展架构的利器 - 动态模块加载核心技术(ClassLoader、反射、依赖隔离)

    一.背景 功能模块化是实现系统能力高可扩展性的常见思路.而模块化又可分为静态模块化和动态模块化两类: 1. 静态模块化:指在编译期可以通过引入新的模块扩展系统能力.比如:通过maven/gradle引 ...

  2. Sphinx 匹配模式

    所谓匹配模式就是用户如何根据关键字在索引库中查找相关的记录. SPH_MATCH_ALL, 匹配所有查询分词(默认模式); 如“手机配件”,不匹配 “我有一部手机”,但可以匹配 “手机坏了,需要找配件 ...

  3. 老师木发的makefile与autotools

    makefile http://scc.qibebt.cas.cn/docs/linux/base/%B8%FA%CE%D2%D2%BB%C6%F0%D0%B4Makefile-%B3%C2%F0%A ...

  4. HDU - 6231:K-th Number (不错的二分)

    Alice are given an array A[1..N]A[1..N] with NN numbers. Now Alice want to build an array BB by a pa ...

  5. Java类和数据结构中常用的方法

    1.Object类里面常用的方法: protected Object clone()创建并返回此对象的一个副本. boolean equals(Object obj)指示其他某个对象是否与此对象“相等 ...

  6. WCF *.svc 自定义地址路由映射

    一般在创建WCF服务时会用Serivce.svc文件访问,地址如:http://localhost/applicationname/Serivce.svc/Name 现在用路由映射成:http://l ...

  7. BZOJ5337 [TJOI2018]str

    题意 小豆参加了生物实验室.在实验室里,他主要研究蛋臼质.他现在研究的蛋臼质是由k个氨基酸按一定顺序构成的.每一个氨基酸都可能有a种碱基序 列si_j 构成.现在小豆有一个碱基串s,小豆想知道在这个碱 ...

  8. CSS 属性:touch-action

    CSS 属性 touch-action 用于指定某个给定的区域是否允许用户操作,以及如何响应用户操作(比如浏览器自带的划动.缩放等). /* Keyword values */ touch-actio ...

  9. Mac各个文件夹表示的意思

    ca参考链接:http://www.jb51.net/os/MAC/130901.html

  10. Cocos2d-x -自己定义动作 圆周运动

    原文地址:http://blog.csdn.net/u012945598/article/details/17605409 在之前的文章中我们以前讲过Cocos2d-x中的各种动作的用法,我们先来简单 ...