JVM定位问题之jstack使用

Posted god-jiang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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程序员有所帮助。

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

JVM故障分析系列之四:jstack生成的Thread Dump日志线程状态

JVM监控及诊断工具-命令之jstack

JVM调优之jstack找出最耗cpu的线程并定位代码

JVM调优之jstack找出最耗cpu的线程并定位代码

JVM调优之jstack找出最耗cpu的线程并定位代码

JVM调优之jstack找出最耗cpu的线程并定位代码