블로그 이름

[JAVA] 스레드 덤프 출력 및 분석 (데드락, 무한루프) 본문

개발/Java

[JAVA] 스레드 덤프 출력 및 분석 (데드락, 무한루프)

Hide 2025. 11. 16. 20:31

운영 중인 서버에서 문제 발생 시 원인 분석을 위한 스레드 덤프 출력 및 분석 방법을 정리하고자 한다.

Java 어플리케이션이 갑자기 느려지거나 응답이 멈추는 등 이슈 발생 시 스레드 덤프를 사용하여 원인을 분석한다. 

스레드 덤프(thread dump) 는 JVM 내부에서 실행중인 모든 스레드의 상태와 스택 정보를 보여주는 로그다.

 

1. 스레드 덤프 출력

 

Java 스레드 덤프 출력 방법은 여러가지가 있다. kill -3, jstack, 톰캣 출력 등 다양하게 있는데 보통 jstack 으로 하면 되므로 jstack 명령어로 출력하는 방법을 정리하고자 한다.

 

jps -l : PID 확인

jstack -l <PID> > threadDump.txt : 스레드 덤프 파일로 출력

 

2. 데드락 찾는 방법

 

데드락이란 스레드가 서로의 락을 기다리며 영원히 진행되지 않는 상황을 말한다.

 

1번에서 출력한 파일에서 아래 문구 검색

Found one Java-level deadlock:

 

해당 문구가 존재한다면 데드락. 

Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x00007f8b08012340 (object 0x00000000d5b8af78, a java.lang.Object),
  which is held by "Thread-2"
"Thread-2":
  waiting to lock monitor 0x00007f8b08014520 (object 0x00000000d5b8b0c0, a java.lang.Object),
  which is held by "Thread-1"

보면 스레드1이 잡은 락을 스레드2가 기다리고 있고, 스레드2가 잡은 락을 스레드1이 기다리는 데드락이다

스택트레이스에서 발생위치 확인 가능. 

데드락은 코드 문제로 락을 거는 순서가 꼬이거나 synchronized 블록이 잘못 설계된 경우 발생한다. 

 

3. CPU 사용률이 높은 스레드 찾는 방법

 

CPU가 치솟는 문제는 대부분 무한 루프에서 발생한다. 이 경우 단순 스레드 덤프만으로 어떤 스레드가 문제인지 찾기 어렵다.

때문에 OS에서 CPU를 많이 쓰는 스레드ID와 JVM 내부 스레드 이름을 매핑해야한다.

 

top -H -p <JVM_PID> : TOP 실행, JVM_PID에 톰캣 PID 넣어주면 된다. 이 때 출력되는 스레드 PID를 기록.

printf "%x\n" <PID> : 스레드ID(TID)를 16진수로 변환

nid=0x<16진수PID입력> : CPU 잡아먹는 스레드 nid 검색

 

스레드 이름 및 상태, 문제 코드 구간을 찾을 수 있다.