zoukankan      html  css  js  c++  java
  • jstack+jdb命令查看线程及死锁堆栈信息

    如果程序挂死,有时使用jstack查看进程中线程信息时,需要添加上-F参数,此时如果有死锁信息,则可能不会打印出死锁堆栈信息,使用jdb则可以查看当前死锁线程的运行堆栈。

    如下模拟一个简单的死锁程序

    package com.demo.bootdemo;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import org.springframework.context.ApplicationListener;
    import org.springframework.context.event.ContextRefreshedEvent;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyListeners implements ApplicationListener<ContextRefreshedEvent> {
    
        private Map map = new HashMap<>();
        private String lock = "aa";
    
        @Override
        public void onApplicationEvent(ContextRefreshedEvent arg0) {
    
            Thread t = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    synchronized (map) {
                        System.out.println(Thread.currentThread().getName() + ": 获得map锁");
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        synchronized (lock) {
                            System.out.println(Thread.currentThread().getName() + ": 获得lock锁");    
                        }
                    }
                }
            }, "t-1");
    
            Thread t2 = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    synchronized (lock) {
                        System.out.println(Thread.currentThread().getName() + ": 获得lock锁");
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        synchronized (map) {
                            System.out.println(Thread.currentThread().getName() + ": 获得map锁");    
                        }
                    }
                }
            }, "t-2");
            
            t.start();
            t2.start();
        }
    
    }

    获取pid

    假设当前不能直接连接27709虚拟机,需要使用参数-F

    可以看出造成死锁的线程未t-1和t-2

    使用jdb连接jvm

    jdb -connect sun.jvm.hotspot.jdi.SAPIDAttachingConnector:pid=27709

    执行threads命令获取所有线程列表

    获取线程“t-1”堆栈信息,如下图,结合上述模拟死锁的代码,很容易就能看出来是哪里的问题

    类似的,获取线程“t-2”的堆栈信息

    通过以上步骤,基本上可以确定问题代码了。

    本例也是匆忙中简单查看了下文档,没有详看,后续有时间在进行补充,jdb文档如下

    https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr011.html#BABDHAHJ

  • 相关阅读:
    常用模块(time,os,sys,collections,random,序列化模块,re)
    python-函数篇
    内置函数——filter和map
    python杂七杂八的用法
    计算机硬件
    操作系统简介
    Django入门
    linux下查看cpu物理个数和逻辑个数
    python反射的妙用
    Python(文件、文件夹压缩处理模块,shelve持久化模块,xml处理模块、ConfigParser文档配置模块、hashlib加密模块,subprocess系统交互模块 log模块)
  • 原文地址:https://www.cnblogs.com/qq931399960/p/11316684.html
Copyright © 2011-2022 走看看