线程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 ...
随机推荐
- Gradle配置IDEA正常识别JPA Metamodel Generator动态生成的代码
我们在使用JPA动态查询构建查询条件时,为了实现安全的类型检查,常常需要引用Hibernate JPA Metamodel Generator自动为我们生成静态元模型类. 而这些类由于编译时由Hibe ...
- poj 1952 最长公共子序列计数
看代码就懂了 不解释 3 1 1 1 1 2 2 2 1 1 1 3 第一个3 和最后一个 3 只需要一个就够了,,, #include<iostream> #include< ...
- hibernate的级联(hibernate注解的CascadeType属性)
[自己项目遇到的问题]: 新增 删除都可以实现 ,就是修改的时候无法同步更新设计三个类: 问题类scask 正文内容类text类 查看数+回复数+讨论数的runinfo类 [正文类和查看数 ...
- Chrome 的书签太多如何分类整理比较好
对于Chrome书签太多,如何进行分类整理,下面给出几种方法~ 工具/原料 电脑 Chrome浏览器 delicious.Diigo等 方法/步骤1 1.把书签中常用网站只保存LOGO,放在书签栏最前 ...
- NETCore中RabbitMQ的使用
NET中RabbitMQ的使用 https://www.cnblogs.com/xibei666/p/5931267.html 概述 MQ全称为Message Queue, 消息队列(MQ)是一种应用 ...
- 重温CLR(七 ) 属性和事件
无参属性 许多类型都定义了能被获取或更高的状态信息.这种状态信息一般作为类型的字段成员实现.例如一下类型包含两个字段: public sealed class Employee{ public str ...
- Linux 绑定双网卡
1.立即关闭iptables并禁用开机自启动[root@mysql01 ~]# /etc/init.d/iptables stop[root@mysql01 ~]# chkconfig iptable ...
- Oracle中遇到的错误
1. ORA-00937: 不是单组分组函数 和 不是group by表达式 --select count(corp_tn),state_code from t_oa_main where cor ...
- 1073 Scientific Notation
题意: 给出科学计数法的形式,转化成常规的表示,要求保留所有的有效位数 思路:纯粹的字符串处理问题,注意边界条件即可.如+1.23E+02这种,转化后是123,既不需要补0,也不需要添加小数点. 代码 ...
- elasticsearch pinyin 拼音分词器
安装pinyin分词 地址:https://github.com/medcl/elasticsearch-analysis-pinyin PUT py_test { "index" ...