• jdk工具之jstack


    语法

    [service@10-176-221-255.drp-project-service-marketing2c.dgdev01 bin]$ ./jstack -h
    	Usage:
    	    jstack [-l] <pid>
    	        (to connect to running process)
    	    jstack -F [-m] [-l] <pid>
    	        (to connect to a hung process)
    	    jstack [-m] [-l] <executable> <core>
    	        (to connect to a core file)
    	    jstack [-m] [-l] [server_id@]<remote server IP or hostname>
    	        (to connect to a remote debug server)
    	
    	Options:
    	    -F  to force a thread dump. Use when jstack <pid> does not respond (process is hung)
    	    -m  to print both java and native frames (mixed mode)
    	    -l  long listing. Prints additional information about locks
    	    -h or -help to print this help message
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    如:jstack -l 打印线程堆栈跟踪信息
    jstack -F 当jvm无响应时,可强制打印线程堆栈

    线程堆栈字段说明:

    在这里插入图片描述

    • ConsumeMessageThread_46: 线程名称
    • #316 线程编号
    • prio=5 优先级,默认:5
    • os_prio=0 表示操作系统级别的优先级
    • tid=0x00007f6bbc00b000 JVM内部线程的唯一标识(通过java.lang.Thread.getId()获取,通常用自增方式实现)
    • nid=0x2a4 对应操作系统下的tid线程号,也就是前面转化的16进制数字
      pid --> nid: printf ‘0x%x’
    • 线程状态 new、runnable、blocked、waiting、time_waiting、terminated
      0x00007f6b069e0000 对象的内存地址,通过jvm内存查看工具,能够看出线程在哪个对象上等待

    线程状态:

    在这里插入图片描述

    (trouble shooting时重点关注标黄的)

    • NEW A thread that has not yet started is in this state.(线程对象创建后,还没没有开始执行的线程处于这种状态)

    • RUNNABLE A thread executing in the Java virtual machine is in this state(在JVM中执行的线程处于这种状态,分Ready和Running)

    • Blocked A thread that is blocked waiting for a monitor lock is in this state.
      线程阻塞,是指当前线程执行过程中,所需要的资源长时间等待却一直未能获取到(比如“锁”),被容器的线程管理器标识为阻塞状态,可以理解为等待资源超时的线程

    • WAITING A thread that is waiting indefinitely for another thread to perform a particular action is in this state(等待另一个线程执行某些特别操作的线程处于这种状态。)

    • TIMED_WAINTING A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state( 等待另一个线程执行某些特别操作的线程(有时间限制)处于这种状态)。线程调用如下方法都会进入TIMED_TAITING状态。
      • Thread.sleep
      • Object.wait with timeout
      • Thread.join with timeout
      • LockSupport.parkNanos
      • LockSupport.parkUntil

    • Waiting on condition 该状态出现在线程等待某个条件的发生。最常见的情况是线程在等待网络的读写,比如当网络数据没有准备好读时,线程处于这种等待状态。而一旦有数据准备好读之后,线程会重新激活,读取并处理数据。
      如果发现有大量的线程都在处在 Wait on condition,从线程堆栈看,正等待网络读写,这可能是一个网络瓶颈的征兆,因为网络阻塞导致线程无法执行,原因有两种:一种情况是网络非常忙,几 乎消耗了所有的带宽,仍然有大量数据等待网络读写;另一种情况也可能是网络空闲,但由于路由等问题,导致包无法正常的到达。
      另外一种出现 Wait on condition的常见情况是该线程在 sleep,等待 sleep的时间到了时候,将被唤醒。

    • Waiting on monitor entry 表示线程正在获取锁。Monitor是 Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁。每一个对象都有,也仅有一个 monitor
      TERMINATED A thread that has exited is in this state (一个已经执行完毕的线程处于这种状态)

    线程状态流转

    在这里插入图片描述

    异常定位思路:

    1. 连续获取几个线程堆栈,追加输出到同一个文件
    2. 先看看有没有死锁
    grep -i "deadlock" aa.tdump
    3. 在看看有没有blocked的线程,根据等待的资源查看是哪个线程hold住了该资源
    类似:
    - locked <0x000000066e1a71b8> (a io.netty.channel.nio.SelectedSelectionKeySet)
    grep -i "blocked" aa.tdump
    4. 看看各个线程状态的统计分布
    当有大量的"Waiting on monitor entry"或者“blocked"的线程时,一般都有问题,存在优化空间
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    常用命令:

    #每隔5秒获取打印一次堆栈信息,打印3次。
    for i in {1..3};do jstack -l 244 >> /tmp/$ip_$(date +%Y%m%d_%T).tdump;i+=1;sleep 5;done
    #统计各个状态的线程数
    grep -i "nid=" -A 1 bb.tdump | grep "java.lang.Thread.State" | awk -F ":" '{state[$2]++}END{for(i in state){print i,state[i]}}'

  • 相关阅读:
    【限定词习题】another / other / others
    mysql存储过程标准模板
    [网鼎杯 2020 青龙组]AreUSerialz
    Vue常见面试题 - 03
    GBase 8s静默安装
    2021 Java面试题大全(整理版)1000+面试题附答案详解,最全面详细,看完稳了!
    HOC的运用
    不相交的线
    uni-app小程序,uview-ui组件样式无法穿透修改的解决办法
    【BUG 弹药库】二分模板的优化
  • 原文地址:https://blog.csdn.net/zpsimon/article/details/126127659