线上高并发时,tomcat挂掉了,应用假死等问题,都可以使用jstack查看线程堆栈的问题。

jstack参数解说

首先线程状态如下:

New: 当线程对象创建时存在的状态,此时线程不可能执行;

Runnable:当调用thread.start()后,线程变成为Runnable状态。只要得到CPU,就可以执行;

Running:线程正在执行;

Waiting:执行thread.join()或在锁对象调用obj.wait()等情况就会进该状态,表明线程正处于等待某个资源或条件发生来唤醒自己;

Timed_Waiting:执行Thread.sleep(long)、thread.join(long)或obj.wait(long)等就会进该状态,与Waiting的区别在于Timed_Waiting的等待有时间限制;

Blocked:如果进入同步方法或同步代码块,没有获取到锁,则会进入该状态;

Dead:线程执行完毕,或者抛出了未捕获的异常之后,会进入dead状态,表示该线程结束

其次,对于jstack日志,我们要着重关注如下关键信息

Deadlock:表示有死锁

Waiting on condition:等待某个资源或条件发生来唤醒自己。比如线程正在sleep,网络读写繁忙而等待.

此时线程状态大致为以下几种:

java.lang.Thread.State: WAITING (parking):一直等那个条件发生;

java.lang.Thread.State: TIMED_WAITING (parking或sleeping):定时的,那个条件不到来,也将定时唤醒自己。

Blocked:阻塞

Waiting on monitor entry:在等待获取锁,意味着它在等待进入一个临界区,所以它在”Entry Set“队列中等待,等待获取监视器。

in Object.wait():获取锁后又执行obj.wait()放弃锁,进入等待队列中。

sleeping:休眠的线程,调用了Thread.sleep()。

runnable:正在运行中。

注意: jstack表示的进程当前的状态哦。如果比如看到状态位RUNNABLE的,表示在你执行jstack时,该线程正在运行中。

对于Waiting on monitor entry 和 in Object.wait()的详细描述:Monitor是 Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁。每一个对象都有,也仅有一个 monitor。从下图中可以看出,每个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 "Running Thread",而其它线程都是 "Waiting Thread",分别在两个队列 " Entry Set"和 "Wait Set"里面等候。

在 "Entry Set"中等待的线程状态是:"Waiting for monitor entry",等待获取锁,在排队呢。

而在 "Wait Set"中等待的线程状态是 "in Object.wait()" 获取了锁,但是执行了wait()操作,线程被挂起,等待被唤醒,同样得重新获取锁。如下图的流转

大量某个状态

如果大量线程在“waiting for monitor entry”:

可能是一个全局锁阻塞住了大量线程。如果短时间内打印的thread dump文件反映,随着时间流逝,waiting for monitor entry 的线程越来越多,没有减少的趋势,可能意味着某些线程在临界区里呆的时间太长了,以至于越来越多新线程迟迟无法进入临界区。

如果大量线程在“waiting on condition”:

可能是获取第三方资源,尤其是第三方网络资源,迟迟获取不到Response,导致大量线程进入等待状态。

所以如果你发现有大量的线程都处在Wait on condition,从线程堆栈看,正等待网络读写,这可能是一个网络瓶颈的征兆,因为网络阻塞导致线程无法执行。

问题状态

Deadlock:表示有死锁

Waiting on condition:等待某个资源或条件发生来唤醒自己。具体需要结合jstacktrace来分析,比如线程正在sleep,网络读写繁忙而等待

Blocked:阻塞

Waiting on monitor entry:在等待获取锁

虽然状态是这么多,但是具体问题还的具体查看,比如等待唤醒的资源,在下一次jstack查看时不存在了,就说明已经获取到锁并执行了。如果存在大量的,且长时间阻塞的那么就说明有很大问题了。

jstack其他参数说明

prio:线程的优先级

tid:线程id

nid:操作系统映射的线程id(16进制)

[0x0000000000000000] :后面末尾的数字,表示线程栈的起始地址。

基础操作

//查找进程号

> jps -lv |grep '应用名称' 或者ps -ef|grep '应用名称'

> jstack 3333 //进程号

top找到堆栈信息

> top //进入top后,shift+H查看线程

找到占用内存较大的线程id

> printf "%x\n" TID 将需要的线程ID转换为16进制格式 (16转10: printf %d\\n 0x5b7f)

> jstack [进程]|grep -A 10 [线程的16进制] //根据jstack找到该线程占用比较大的堆栈信息。

> jstack 13333 |grep -A 10 54f2

其他命令:

输出该进程拥有的线程总数

ps -mp 5841 -o THREAD,tid,time | wc -l

输出占用cpu最大的前10线程

ps -mp 5841 -o THREAD,tid,time | sort -rn | head -10

参考地址

java 线程休眠 假死,java多线程-jstack线程阻塞问题排查相关推荐

  1. java线程休眠sleep函数_Java多线程中sleep()方法详解及面试题

    一. Java线程生命周期(五个阶段) 新建状态就绪状态运行状态阻塞状态死亡状态 如图 二.sleep方法 API中的解释 static voidsleep(long millis) 使当前正在执行的 ...

  2. java runnable wait_面试官:都说阻塞 I/O 模型将会使线程休眠,为什么 Java 线程状态却是 RUNNABLE?...

    摘要: 原创出处 https://studyidea.cn 「公众号:程序通事 」欢迎关注和转载,保留摘要,谢谢! 使用 Java 阻塞 I/O 模型读取数据,将会导致线程阻塞,线程将会进入休眠,从而 ...

  3. new thread后会阻塞主程序吗_阻塞模型将会使线程休眠,为什么 Java 线程状态却是 RUNNABLE?...

    使用 Java 阻塞 I/O 模型读取数据,将会导致线程阻塞,线程将会进入休眠,从而让出 CPU 的执行权,直到数据读取完成.这个期间如果使用 jstack 查看线程状态,却可以发现Java 线程状态 ...

  4. 既然阻塞 I/O 会使线程休眠,为什么 Java 线程状态却是 RUNNABLE?

    使用 Java 阻塞 I/O 模型读取数据,将会导致线程阻塞,线程将会进入休眠,从而让出 CPU 的执行权,直到数据读取完成.这个期间如果使用 jstack 查看线程状态,却可以发现Java 线程状态 ...

  5. wxpython多线程 假死_wxpython中利用线程防止假死的实现方法

    前段时间我编写了一个工业控制的软件,在使用中一直存在一个问题,就是当软件检索设备时,因为这个功能执行的时间比较长,导致GUI界面假死,让用户分辨不清楚软件到底仍在执行,还是真的挂掉了.(虽然我设计了同 ...

  6. java ee ide 假死_Eclipse编辑jsp、js文件时卡死现象的解决办法汇总

    使用Eclipse编辑jsp.js文件时,经常出现卡死现象,在网上百度了N次,经过N次优化调整后,卡死现象逐步好转,具体那个方法起到作用,不太好讲.将所有用过的方法罗列如下: 1.取消验证 windo ...

  7. qt开启线程界面假死问题解决

    一.前言 在 使用qt高速读取传感器数据时,如果想要将数据实时刷新在界面,就需要开启一个线程单独去跑读取数据函数,并反馈给主程序,否则在主程序中读取和刷新界面会很卡很卡,但是在开启多线程,无外接鼠标键 ...

  8. 2021-11-24 micropython esp32休眠假死 唤醒 rtc nvs btree数据保持

    首先本次记录时MICROPYTHON 在ESP32环境下的记录,这里需要声明你使用的micropython 的版本固件不应该太古老,根据我的经验,有些早期固件不支持以下测试,或者不具备相应功能,固件嘛 ...

  9. wxpython多线程 假死_wxpython多线程防假死与线程间传递消息实例详解

    wxpython中启用线程的方法,将GUI和功能的执行分开. 网上关于python多线程防假死与线程传递消息是几年前的,这里由于wxpython和threading模块已经更新最新,因此给出最新修改代 ...

  10. java如何让线程休眠一分钟_如何使线程在java中休眠特定的时间?

    当你的线程被中断击中时,它将进入InterruptedException catch块.然后,您可以检查线程花费了多少时间睡觉,并计算出睡眠时间.最后,不要吞咽异常,恢复中断状态是很好的做法,以便调用 ...

最新文章

  1. crtmpserver 配置说明_crtmpserver 流媒体服务器 集群 安装配置
  2. CTFshow 信息收集 web18
  3. 智能理财在国内国外的发展现状
  4. javascript数组查重方法总结
  5. c语言垂直制表的作用,c语言中“\”的用途
  6. VTK:图片之ImageMagnify
  7. linux服务器之查看内存使用情况
  8. vb mysql边记录边统计_vb6 数据库 增加记录
  9. 无监督︱异常、离群点检测 一分类——OneClassSVM
  10. KNN(二)--近似最近邻算法ANN
  11. spark sql读取hive底层_SparkSQL读取Hive数据插入Redis
  12. OpenStack峰会喊你回家吃饭
  13. 让openkore 更节省你的CPU和内存
  14. tcpdump使用详解及数据包分析
  15. KDA的新宠儿,金贝KD6,更大算力,探索无限可能
  16. python+twilio实现打电话和发短信功能
  17. 【POJ3585】Accumulation Degree 二次扫描与换根法
  18. [Unity] 制作游戏 赛车小游戏
  19. linux里添加网卡,Linux添加虚拟网卡的多种方法
  20. php mql获取结果集,mql查询删除更新嵌入求指导php

热门文章

  1. 基于matlab的字符识别系统
  2. Linux上恢复被删除的文件或目录
  3. 中国传统文化课程笔记
  4. 让Yahoo!奇摩害怕的无名小站
  5. 工程实践中的体系与系统
  6. php程序员工作日记,PHP程序员战地日记
  7. 51单片机红外遥控继电器电路部分设计
  8. 专利分析:数字人民币的“双离线”支付问题
  9. java kdj macd_很好用的KDJ与MACD结合指标
  10. uni-app实现问卷调查试卷