dump 라인은 잠긴 자물쇠를 도망갈 수 없게 합니다

4183 단어 JVM
어제 어떤 사람이 물었다. "프로그램이 실행될 때, 프로그램이 사라진 자물쇠가 발생했는지, 만약 사라진 자물쇠가 발생했다면, 어떻게 사라진 자물쇠가 발생한 위치를 찾을 수 있습니까?';dump 라인의 데이터를 붙였는데, 오늘 또 어떤 사람이 나에게 어떻게 dump 파일에서 사라진 자물쇠를 분석하느냐고 묻는다.
1. 먼저 사라진 자물쇠를 구성한다. 코드는 다음과 같다.
 
 
public class Deadlocker {

    private static Object lock_1 = new int[1];
    private static Object lock_2 = new int[1];

    public class Thread1 extends Thread {

        @Override
        public void run() {
            System.out.println("thread 1 start");
            synchronized (lock_1) {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("thread 1 get lock 1 need lock 2");
                synchronized (lock_2) {
                }
            }
            System.out.println("thread 1 end");
        }
    }

    public class Thread2 extends Thread {

        @Override
        public void run() {
            System.out.println("thread 2 start");
            synchronized (lock_2) {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("thread 2 get lock 2 need lock 1");
                synchronized (lock_1) {
                }
            }
            System.out.println("thread 2 end");
        }
    }

    public static void main(String[] args) {
        Thread1 thread1 = new Deadlocker().new Thread1();
        Thread2 thread2 = new Deadlocker().new Thread2();
        thread1.start();
        thread2.start();
    }
}

 
 
2. 실행 결과는 다음과 같다.
 
 
thread 1 start
thread 2 start
thread 1 get lock 1 need lock 2
thread 2 get lock 2 need lock 1
 
 
3. 분석:
프린터의 결과는 라인 1과 라인 2가 잠겨 있는 것을 쉽게 분석할 수 있다.서로 상대방이 가지고 있는 자물쇠가 필요하다.
 
4, 사용: jps에서 루틴 id를 보고: jstack 루틴 id > dumpthread 명령을 사용합니다.일부 결과는 다음과 같다(각종 gc 스레드 제거...):
 
섹션 1:
 
 
"Thread-1"prio=10 tid=0x0000000040a49800 nid=0x2d1e waiting for monitor entry [0x00007f50eda98000]
   java.lang.Thread.State: BLOCKED (on object monitor)
at Deadlocker$Thread2.run(Deadlocker.java:47)
- waiting to lock <0x00000007d6f97ec8> (a [I)
- locked <0x00000007d6f97ee0> (a [I)
 
"Thread-0"prio=10 tid=0x0000000040a47800 nid=0x2d1d waiting for monitor entry [0x00007f50edb99000]
   java.lang.Thread.State: BLOCKED (on object monitor)
at Deadlocker$Thread1.run(Deadlocker.java:28)
- waiting to lock <0x00000007d6f97ee0> (a [I)
- locked <0x00000007d6f97ec8> (a [I)
 
.....기타 다양한 스레드
 
여기서 두 라인이 BLOCKED 상태에 있고 각자 자물쇠를 기다리고 있음을 알 수 있다(0x00000007d6f97ec8과 0x00000007d6f97ee0)
 
섹션 2:
 
 
Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x0000000040a33dd8 (object 0x00000007d6f97ec8, a [I),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x0000000040a365e0 (object 0x00000007d6f97ee0, a [I),
  which is held by "Thread-1"
 
이것은 보자마자 더욱 명백해졌다.자바의 사라진 자물쇠를 발견했다고Thread-1이lock을 기다리고 있는데, 이 자물쇠는Thread-0이 가지고 있고,
Thread-0은 다른 lock을 기다리고 있는데, 이 자물쇠는Thread-1에 의해 소지되어 있다
 
Java stack information for the threads listed above:
===================================================
"Thread-1":
at Deadlocker$Thread2.run(Deadlocker.java:47)
- waiting to lock <0x00000007d6f97ec8> (a [I)
- locked <0x00000007d6f97ee0> (a [I)
"Thread-0":
at Deadlocker$Thread1.run(Deadlocker.java:28)
- waiting to lock <0x00000007d6f97ee0> (a [I)
- locked <0x00000007d6f97ec8> (a [I)
 
Found 1 deadlock.
 
위의 빨간색 부분도 사라진 자물쇠의 위치를 정확하게 조회할 수 있다.
 
물론 두 번째 부분은 자바5 이상 버전만 있다고 합니다(미검증).dump 데이터는 첨부 파일 참조
 
 
이 사이트는pay for your wishes 지원

좋은 웹페이지 즐겨찾기