jstack的使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jstack的使用相关的知识,希望对你有一定的参考价值。

参考技术A

通过jstack,我们可以轻松得知jvm中各个线程的工作情况.

利用ps -aux 找出我们的java线程41,然后再用jstack -l 41,就可以查看jvm此刻运行的所有线程.

下面是截取的两个jvm运行的普通线程,一个是守护线程,另外一个是用户线程.
守护线程 守护线程是指给程序提供通用性支持的线程,他不属于程序,gc就是一个很称职的守护线程.守护线程是为用户线程提供服务的,也就是说如果没有用户线程,守护线程就没有存活下去的意义,在jstack中查出来的线程信息中,守护线程有个 daemon 的标志
用户线程 用户线程通常是程序自己开启的.jvm会随着所有的用户程序关闭而关闭

在下面的线程信息中 :
HikariPool-1 connection closer 是线程的名字,在Java中可以通过Thread.currentThread().getName()来查看线程名字
prio 应该是线程的优先级
tid jvm中的线程id
nid tid映射的操作系统中的线程id,非常有用,不过这里是用16进制的表示, 可以通过 printf "%x\\n" 十进制数字 查找一个十进制数字的十六进制表示
0x00007fa735a2a000 线程栈的起始地址
TIMED_WAITING 线程状态
0x00000006e941b160 资源名称,等待某个资源被释放,说明有其他线程锁住了该资源,一般是 locked <0x00000006e941b160>

线程状态

假如java进程经常出现卡慢,cpu经常会爆满,这时候我们考虑一下是否是我们某些线程太占cpu,导致其他线程不能好好工作.可以通过以下步骤观察

JVM定位问题之jstack使用

背景

本人在刚开始接触企业级开发的时候,就曾经写过一段类似于死循环的代码。然后把这个代码发布到线上,Grafana显示该应用上线后CPU一直接近100%,于是在大佬的帮助下用jstack定位到问题并且解决了,所以总结一下jstack的使用吧。

jstack描述

此命令是为Java进程或核心文件或远程调试服务器打印Java线程的堆栈跟踪。jstack可以同时打印所有线程的Java和本机栈帧。jstack常用于定位线程的死循环、死锁等情况。

场景模拟

package JVM;

import java.util.ArrayList;
import java.util.List;

/**
 * Jstack演示
 *
 * @author god-jiang
 * @date 2021/5/3 15:00
 */
public class JstackDemo 
    public static void main(String[] args) 
        // 死循环
        List<Integer> list = new ArrayList<Integer>() 
            
                add(666);
            
        ;
        System.out.println("开始无限读数据");
        while (true) 
            list.get(0);
        
    

当运行以上的程序,由于出现了死循环,往往表现出来的时候是CPU100%,这个时候我们应该进去服务器,用top命令查找出CPU占用率最高的进程pid。

用top命令发现了CPU占用率最高的pid为1639,这个时候就要用top -H -p 1639去该进程里面查看各个线程的情况,找到线程占用率最高的nid。(由于博主用的是mac电脑,没有top -H命令,所以就不演示这一步了~~~)

可以用jps查出目前正在运行的Java进程,知道1639对应的是JstackDemo这个java进程

然后可以用jstack pid来分析线程的堆栈情况

可以发现nid=0xe03线程出现了等待,初步判断为死循环。(WAITING一般为死循环,BLOCKED一般为死锁),看到是JstackDemo的22行出问题,所以去程序找到对应的行数分析。

最后定位到这里,发现是死循环引起的,根据不同的场景和情况去解决即可。

重点归纳

发现CPU100%的解决思路大致可以分为以下:

  1. 用top查出CPU占用率高的进程pid
  2. 用jps大致确定pid是对应线上的哪个进程导致的
  3. 用top -H -p pid找到该pid下线程占用率最高的线程nid,此时nid是10进制
  4. 用jstack pid | grep nid查出对应的堆栈情况,这里要注意nid是要转换为16进制
  5. 根据WAITING或者BLOCKED大致判断是死循环还是死锁,然后回到程序中定位代码并且根据业务场景解决

总结

根据本人在企业开发遇到的一次线上CPU100%的事故,然后引起对Jstack的学习,知道jstack的作用还有对线上问题排查和定位的过程。希望以上分享对Java程序员有所帮助。

以上是关于jstack的使用的主要内容,如果未能解决你的问题,请参考以下文章

jstack 使用一例

Jstack 命令分析

jstack的使用

jstack介绍

JVM定位问题之jstack使用

JVM定位问题之jstack使用