• jstack问题定位分析


    目录

    1、jstack是什么

    2、jstack的使用

    1、jstack是什么

    jstack是java虚拟机自带的一种堆栈跟踪工具。jstack用来打印出给定的java进程ID或者core file或者远程调试服务的java堆栈信息。

    主要是用于生成java虚拟机当前时刻的线程快照,线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环,请求外部资源导致的长时间等待等。

    线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程在后台做什么事,或者等待什么资源。

    jstack的主要作用:帮助定位程序出现问题的原因,如长时间停顿、cpu占用率高等问题。

    2、jstack的使用

    jstack的使用可以结合top命令查看出当前系统cpu内存使用率最高的进程pid。

    jstack的使用步骤为:

    1、先使用jps、ps ef|grep java 查看当前Java进程的pid,严重的时候可以使用top命令查看当前系统cpu、内存使用率最高的进程pid。

    1. [root@localhost opt]# top
    2. top - 16:24:42 up 51 days, 20:51, 6 users, load average: 2.31, 2.61, 2.82
    3. Tasks: 1283 total, 1 running, 1282 sleeping, 0 stopped, 0 zombie
    4. %Cpu(s): 8.7 us, 0.7 sy, 0.0 ni, 90.3 id, 0.0 wa, 0.0 hi, 0.2 si, 0.0 st
    5. KiB Mem : 23083337+total, 12588844+free, 95284000 used, 9660940 buff/cache
    6. KiB Swap: 4194300 total, 4194300 free, 0 used. 13450121+avail Mem
    7. PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
    8. 4017 root 20 0 6675664 4.9g 5868 S 125.2 2.2 94141:37 xxxxx
    9. 29938 root 20 0 18.6g 2.5g 13828 S 110.8 1.1 122:35.90 java
    10. 12303 root 20 0 6861556 637644 264096 S 33.4 0.3 1537:42 xxxx
    11. 3327 root 20 0 2951676 227816 156864 S 4.9 0.1 202:30.71 xxxx
    12. 3874 root 20 0 355696 6792 5908 S 3.3 0.0 2660:46 xxxx
    13. ......

    我们可以看到产生死锁的java进程的pid为29938

    死锁:两个线程互相得到锁1、锁2,然后线程1等待线程2释放锁2,线程2等待线程1释放锁1.两者互相等待释放,于是就产生了死锁。

    如何避免死锁产生:

    1、按照顺序加锁:线程间加锁的顺序各不一致,就会导致死锁,如果每个线程都按同一个的加锁顺序这样就不会出现死锁。

    2、获取锁时限;在每个获取锁的时候加上一个时限,如果超过某个时间就放弃获取锁。

    3、死锁检测:按照线程间获取锁的关系检测线程之间是否发生死锁,如果发生死锁就执行一定的策略,如终断线程或回滚操作等。

    2、使用top -Hp 29938 查看进程里面占用资源最多的线程。

    1. [root@localhost opt]# top -Hp 29938
    2. top - 16:25:22 up 51 days, 20:52, 6 users, load average: 2.13, 2.53, 2.78
    3. Threads: 101 total, 1 running, 100 sleeping, 0 stopped, 0 zombie
    4. %Cpu(s): 9.2 us, 1.0 sy, 0.0 ni, 89.6 id, 0.0 wa, 0.0 hi, 0.3 si, 0.0 st
    5. KiB Mem : 23083337+total, 12591091+free, 95194368 used, 9728104 buff/cache
    6. KiB Swap: 4194300 total, 4194300 free, 0 used. 13460681+avail Mem
    7. Unknown command - try 'h' for help
    8. PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
    9. 31201 root 20 0 18.6g 2.4g 13828 R 99.0 1.1 108:04.58 java
    10. 29945 root 20 0 18.6g 2.4g 13828 S 0.7 1.1 0:32.57 java
    11. 29950 root 20 0 18.6g 2.4g 13828 S 0.7 1.1 0:32.50 java
    12. 29954 root 20 0 18.6g 2.4g 13828 S 0.7 1.1 0:32.57 java
    13. 29955 root 20 0 18.6g 2.4g 13828 S 0.7 1.1 0:32.54 java
    14. 29958 root 20 0 18.6g 2.4g 13828 S 0.7 1.1 0:32.56 java
    15. 29960 root 20 0 18.6g 2.4g 13828 S 0.7 1.1 0:32.56 java
    16. ........

    此时我们可以看到占用资源最多的线程是:31201

    3、然后使用printf "%x\n"  31201   把线程pid转换成16进制数,就得到了:79e1

    1. [root@localhost opt]# printf "%x\n" 31201
    2. 79e1

    4、使用jstack 29938 | grep -20 79e1命令查询该线程阻塞的地方。(其中的20表示20行)

    然后追溯跟踪到的信息 ,然后根据提示去排查产生死锁的原因。

  • 相关阅读:
    什么是视频剪辑SDK?
    java毕业设计家教管理系统mybatis+源码+调试部署+系统+数据库+lw
    【BOOST C++ 线程】boost::thread库的基本使用方法总结
    UI设计师的主要工作内容优漫动游
    Vue3学习(二)
    华为云云服务器评测|详解 Nacos 安装部署
    Springboot解决模块化架构搭建打包错误找不到父工程
    IDEA中 tomcat 控制台中文乱码解决
    Linux新的IO模型io_uring
    决策树模型(3)决策树的生成与剪枝
  • 原文地址:https://blog.csdn.net/m0_52165864/article/details/127961271