资讯 小学 初中 高中 语言 会计职称 学历提升 法考 计算机考试 医护考试 建工考试 教育百科
栏目分类:
子分类:
返回
空麓网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
空麓网 > 计算机考试 > 软件开发 > 后端开发 > Java

使用jstack排查JVM进程死锁

Java 更新时间: 发布时间: 计算机考试归档 最新发布

使用jstack排查JVM进程死锁

文章目录
  • 前言
  • 例子程序
  • 排查过程
    • 找出Java进程ID
    • 找出等待相同锁的多个线程
    • 其他快速查找方式
  • 总结

前言

在Linux系统使用JDK自带的jstack指令分析输出的线程信息排查死锁的详细步骤。

例子程序

下面是一个模拟线程死锁的例子程序,编译(javac DeadLockSample.java)后执行(java DeadLockSample)这个程序来启动一个JVM进程。

其中一个线程会成功获取到DeadLockSample的Class对象锁持续打印(locking…),由于是死循环,所以锁不会释放,其他两个意图获取锁的线程只能无限等待。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class DeadLockSample {

    private static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(3);

    public static void main(String[] args) {
        EXECUTOR.submit(DeadLockSample::doSomething);
        EXECUTOR.submit(DeadLockSample::doSomething);
        EXECUTOR.submit(DeadLockSample::doSomething);
    }

		  
    private static synchronized void doSomething() {
        try {
            while (true) {
                System.out.println("locking...");
                TimeUnit.SECONDS.sleep(3);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
排查过程 找出Java进程ID

通过JDK自带的jps指令列出服务器上所有Java进程,找到我们排查死锁的进程ID。

找出等待相同锁的多个线程

执行jstack 查看进程中所有线程运行信息。

jstack 8200

从输出的信息中我们可以看到有两个线程(线程名为pool-1-thread-2和pool-1-thread-3)在等待(waiting to lock)同一个类型(a java.lang.Class for DeadLockSample)对象(0x00000000f0c72bb8)的锁。

而持有(locked)这个类型(a java.lang.Class for DeadLockSample)对象(0x00000000f0c72bb8)锁的线程名为(pool-1-thread-1)。

到此我们已经找出了持有死锁的线程,关键在于锁肯定被一个线程持有,如果有线程在等待同一把锁,那么他们锁定(lock)和等待(waiting to lock)的对象类型(a java.lang.Class for DeadLockSample)和对象实例的十六进制唯一 标识(0x00000000f0c72bb8)是一样的。

其他快速查找方式

由于jstack输出的信息非常多,查找关键信息不是很方便,通过grep命令过滤只输出我们需要的信息可以更快的定位问题线程,格式为jstack | grep ‘<过滤关键字>’

  • 找出等待锁的相关信息
jstack 8200 | grep 'waiting to lock'

  • 找出所有持有锁的相关信息
jstack 8200 | grep 'locked'

  • 将jstack结果输出到指定文件,格式为jstack [Java进程ID] > [文件名],> 代表覆盖,>> 代表追加。
jstack 8200 > 8200.text
# jstack 8200 >> 8200.text

最后根据十六进制唯一标识在文件中查找相关线程信息也可以定位问题。

总结

排查主要使用jstack命令输出线程运行相关信息,然后找出持有、等待锁的线程,并根据锁的对象实例的十六进制唯一标识来判断是否是通一把锁。

虽然知道了死锁的相关信息,但还需要根据线程名、对象的类型、线程运行状态、方法堆栈等信定位到代码内的具体位置。

其实有更快的方式是使用阿里的 Arthas,如果不方便或者没有这个工具包使用本文方式是比较合适的,因为指令JDK自带无需依赖其他工具。

转载请注明:文章转载自 http://www.konglu.com/
本文地址:http://www.konglu.com/it/353708.html
免责声明:

我们致力于保护作者版权,注重分享,被刊用文章【使用jstack排查JVM进程死锁】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理,本文部分文字与图片资源来自于网络,转载此文是出于传递更多信息之目的,若有来源标注错误或侵犯了您的合法权益,请立即通知我们,情况属实,我们会第一时间予以删除,并同时向您表示歉意,谢谢!

我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2023 成都空麓科技有限公司

ICP备案号:蜀ICP备2023000828号-2