线程dump
当应用程序运行变慢或者发生故障时,可能通过分析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的更多相关文章
- jstack和线程dump分析
转自:http://jameswxx.iteye.com/blog/1041173 一:jstack jstack命令的语法格式: jstack <pid>.可以用jps查看java进程 ...
- 不依赖jstack的java 线程dump和死锁检查工具
java线程dump可以使用jdk的命令"jstack pid"完成,死锁检查可以用jconsole查看到.这两个工具是java调试的常用方法. 我遇到的问题是:在sles11s ...
- [转]java线程安全、jstack\线程dump、内存查看分析总结
http://jameswxx.iteye.com/blog/808546 java线程安全总结二 http://jameswxx.iteye.com/blog/1041173 jstack和线程du ...
- java线程dump分析工具
jstack和线程dump分析 java程序性能分析之thread dump和heap dump 一.[内存dump] jmap –dump:live,format=b,file=heap.bin ...
- JAVA线程dump的分析
Java 的线程 线程是指能独立于程序的其它部分运行的执行单元. JAVA语言能够很好的实现多线程的程序.我们在调试程序,或者在开发后期需要做性能调优的时候,往往也需要了解当前程序正在运行的线程的状态 ...
- Java中如何获取到线程dump文件
死循环.死锁.阻塞.页面打开慢等问题,打线程dump是最好的解决问题的途径.所谓线程dump也就是线程堆栈,获取到线程堆栈有两步: (1)获取到线程的pid,可以通过使用jps命令,在Linux环境下 ...
- Java线程Dump分析工具--jstack【转载】
jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使 ...
- Java线程Dump分析工具--jstack(转)
jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使 ...
- Java线程Dump分析工具--jstack
jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使 ...
- 使用jstack和TDA进行java线程dump分析
转载:http://blog.csdn.net/everlasting_188/article/details/51943095 1.jstack重点关注 命令行:jstack [-l][F] pid ...
随机推荐
- 头文件string.h中的函数及使用方法
来源:http://blog.csdn.net/tsyj810883979/article/details/5116817 字符串拷贝1 @函数名称: strdup函数原型: char *st ...
- sublime上配置markdown
等等等等 简书一个不错的教程:Sublime Text3的Markdown配置 补充说明:第一步可以直接找 Tools-->install package control. ^.^ ...
- win10如何在局域网中设置一台电脑的固定ip地址
在工作和生活中,经常要遇到远程访问一台电脑的情况,但是在局域网中如果不进行设置,通常一台电脑的ip是自动生成的,,没有固定,这就导致下次访问这个地址时,不能正常访问,下面就交大家如何在win10系统中 ...
- bzoj 4472 salesman
Written with StackEdit. Description 某售货员小\(T\) 要到若干城镇去推销商品,由于该地区是交通不便的山区,任意两个城镇 之间都只有唯一的可能经过其它城镇的路线. ...
- self = [super init] 最终解释
答: init 中调用super的 init方法来初始化自己所包含有的父类信息 1.内存分配 内存应该在[Class alloc]的时候就已经分配了,大小和类型应该由对应的Clas ...
- 简述MVC模式
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...
- FastAdmin 在 CRUD 时出现 exec() has been disabled for security reasons 怎么办?
FastAdmin 在 CRUD 时出现 exec() has been disabled for security reasons 怎么办? 有小伙伴提问 FastAdmin 在 CRUD 时出现 ...
- 用xshell-ssh连接服务器被经常意外中断
xshell突然中断报错 Socket error Event: 32 Error: 10053.Connection closing...Socket close. Connection close ...
- 配置MapReduce插件时,弹窗报错org/apache/hadoop/eclipse/preferences/MapReducePreferencePage : Unsupported major.minor version 51.0(Hadoop2.7.3集群部署)
原因: hadoop-eclipse-plugin-2.7.3.jar 编译的jdk版本和eclipse启动使用的jdk版本不一致导致. 解决方案一: 修改myeclipse.ini文件即可解决. ...
- PL/SQL 训练07--发现问题
drop table ma_schedue_task ; ---test_task(:1,:2) create table ma_schedue_task( created_by ) default ...