美文网首页
jstack实战死循环与死锁

jstack实战死循环与死锁

作者: 宁静的猫 | 来源:发表于2019-09-30 11:36 被阅读0次

jstack可以打印jvm内所有的线程,利用jstack可以排除程序运行时出现的死循环或者死锁问题。

1、实战死循环

1、编写测试代码

public class TestDeadLoop {
    public static void main(String[] args) {
        while (true){
            System.out.println("deadloop");
        }
    }
}

2、在Linux中,可以通过top命令找出java进程中cpu利用率特别高的那个线程

top -p [pid] -H
top命令

在上图中,cpu利用率最高的线程pid是30712。

而在Windows中,可以使用plist命令


plist命令

在上图中,Tid为20240的Cswtch达到了6496,将20240转为16进制,为4f10,记住这个数字,后面有用。

3、使用jstack打印所有线程,保存到指定文件

jstack  20240 > 20240.txt

打开文件,搜索4f10,即可找到出问题的线程的堆栈了


线程信息

这样,就可以找出死循环的那个线程在做什么事情了~

2、实战死锁

1、编写测试代码

public static void main(String[] args) {
        Object lock1 = new Object();
        Object lock2 = new Object();

        new Thread(() -> {
            synchronized (lock1){
                try {
                    Thread.sleep(1000);
                    synchronized (lock2){
                        System.out.println("get lock 1 and lock 2");
                    }

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "thread-1").start();

        new Thread(() -> {
            synchronized (lock2){
                try {
                    Thread.sleep(1000);
                    synchronized (lock1){
                        System.out.println("get lock 1 and lock 2");
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "thread-2").start();

    }

2、运行代码,发现程序一直没有运行结束

程序一直没有结束
3、在这里程序的进程id为11704,执行jstack 11704> 11704.txt,得到堆栈信息
"thread-2" #15 prio=5 os_prio=0 tid=0x000000001b41d000 nid=0xfa78 waiting for monitor entry [0x000000001bcce000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.tony.springboot.spring.TestDeadLock.lambda$main$1(TestDeadLock.java:28)
    - waiting to lock <0x00000000d65128d8> (a java.lang.Object)
    - locked <0x00000000d65128e8> (a java.lang.Object)
    at com.tony.springboot.spring.TestDeadLock$$Lambda$2/41903949.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:748)

"thread-1" #14 prio=5 os_prio=0 tid=0x000000001b417800 nid=0xee2c waiting for monitor entry [0x000000001bbce000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.tony.springboot.spring.TestDeadLock.lambda$main$0(TestDeadLock.java:14)
    - waiting to lock <0x00000000d65128e8> (a java.lang.Object)
    - locked <0x00000000d65128d8> (a java.lang.Object)
    at com.tony.springboot.spring.TestDeadLock$$Lambda$1/483422889.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:748)

可以看出,thread-1获得了0x00000000d65128d8这把锁,等待0x00000000d65128e8这把锁,而thread-2获得了0x00000000d65128e8这把锁,等待0x00000000d65128d8这把锁。从这里就可以判断出,程序内部发生了死锁。
另外,翻到11704.txt文件的最下面,可以看到如下信息:

Found one Java-level deadlock:
=============================
"thread-2":
  waiting to lock monitor 0x00000000183e3638 (object 0x00000000d65128d8, a java.lang.Object),
  which is held by "thread-1"
"thread-1":
  waiting to lock monitor 0x00000000183df598 (object 0x00000000d65128e8, a java.lang.Object),
  which is held by "thread-2"

Java stack information for the threads listed above:
===================================================
"thread-2":
    at com.tony.springboot.spring.TestDeadLock.lambda$main$1(TestDeadLock.java:28)
    - waiting to lock <0x00000000d65128d8> (a java.lang.Object)
    - locked <0x00000000d65128e8> (a java.lang.Object)
    at com.tony.springboot.spring.TestDeadLock$$Lambda$2/41903949.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:748)
"thread-1":
    at com.tony.springboot.spring.TestDeadLock.lambda$main$0(TestDeadLock.java:14)
    - waiting to lock <0x00000000d65128e8> (a java.lang.Object)
    - locked <0x00000000d65128d8> (a java.lang.Object)
    at com.tony.springboot.spring.TestDeadLock$$Lambda$1/483422889.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:748)

Found 1 deadlock.

jstask帮我们找出了这个死锁。所以,我们可以通过jstack来定位死锁并解决问题。

相关文章

  • jstack实战死循环与死锁

    jstack可以打印jvm内所有的线程,利用jstack可以排除程序运行时出现的死循环或者死锁问题。 1、实战死循...

  • jstack命令解析

    jstack用法 jstack查看输出 jstack统计线程数 jstack检测死锁 死锁代码 死锁日志 jsta...

  • jstack 死锁 死循环 线程阻塞

    1.死循环: 1.jps找出所属进程的pid: 2.使用jstack找到跟代码相关的线程,为main线程,处于ru...

  • 如何去检测死锁

    如何检测死锁 死锁预防 让线程获取锁的顺序一致 死锁检测 jps 查看java 进程信息 jstack +进程号 ...

  • 线程死循环与死锁 jstack(cpu利用率高)

    导出jstack文件 线程的状态 线程更多知识参考:https://mp.weixin.qq.com/s/Gsxe...

  • 为何出现死锁

    为何出现 jps 和 jstack 工具查看死锁如何解决

  • 死锁排查

    jps -l 找到执行的进程jstack 7316 看到死锁报告

  • 分析程序死锁及定位

    检测程序死锁 可以使用jstack命令, jstack you_pid进程的pid可以在任务管理器中找到,你也可以...

  • JVM常用命令之-----jstack

    Jstack jstack命令主要用于调试java程序运行过程中的线程堆栈信息,可以用于检测死锁,进程耗用cpu过...

  • 死锁的排查方法

    本地模拟死锁环境 idea可以查看线程状态image.png jstack定位image.pngimage.png...

网友评论

      本文标题:jstack实战死循环与死锁

      本文链接:https://www.haomeiwen.com/subject/zlovuctx.html