본문 바로가기

알아두면 좋은 IT 지식/Java

[IT] Java Thread Dump 생성 및 분석 방법 (kill -3 / jstack / jcmd)

Java 프로세스의 현재 상태를 확인하는데 가장 좋은 방법 중 하나는 Thread Dump를 생성해 보는 것이다.
대부분의 Java 프로세스는 여러개의 쓰레드로 구성되어 있고, 각각의 쓰레드가 현재 무슨 일을 하고 있는지 알 수 있다면 Java 프로세스의 현재 상태나 이상 여부를 어느정도 알 수 있다.
일반적으로 '5초 간격으로 3번을 생성하라'는 말이 있지만 이는 상황에 따라서 반드시 조절이 필요하다.
예를 들어서 어떤 서비스가 10초간 동작하는데 중간에 발생하는 3초 정도의 지연 현상을 분석해야 한다면 최소한 2초 간격으로 5번은 발생 시켜야지만 해당 현상을 확인해 볼 수 있을 것이다.


kill -3 PID

kill -3 1111

리눅스 OS에서 표준 출력으로 쓰레드 덤프를 발생 시킨다.
jdk 1.4이하 버전에서 많이 쓰이며, OS에서 동작하기 때문에 현재 동작중인 java 프로세스의 자원을 많이 사용하지 않는 장점이 있다.
단, java 프로세스가 백그라운드로 동작하는 경우 Thread Dump가 콘솔에 남지 않기 때문에 이 로그 위치를 지정해주기 위한 아래 jvm 옵션 추가가 필요하다.

-XX:+UnlockDiagnosticVMOptions
-XX:+LogVMOutput
-XX:LogFile=$LOG_HOME/jvm.log


jstack PID

jstack -l 1111 >> jstack.tdump

jdk1.5이상 버전에서 많이 쓰이며, java에서 제공하는 jstack 유틸리티를 사용하여 Thread Dump를 발생 시킨다.
현재 실행중인 프로세스에 영향을 미칠 수 있으므로 jdk1.8이상 부터는 jcmd 사용을 권장 한다.


jcmd PID Thread.print

jcmd 1111 Thread.print >> jcmd.print

jdk1.8이상 버전에서 많이 쓰이며, java에서 제공하는 jcmd 유틸리티를 사용하여 Thread Dump를 발생 시킨다.
Oracle 문서에 의하면 향상된 진단 및 성능 오버 헤드 감소를 위해서 jstack 유틸리티 대신 jcmd를 사용하는 것이 좋다고 한다.


실제 사용 사례

PID가 5296인 java 프로세스의 분석을 위해서 2초 간격으로 5번 Thread Dump를 발생 시켜서 시간별로 파일로 저장하는 예제로 sh파일로 저장해 놓고 사용하면 편리하다.

for ((i=0; i<5; i++)); do
jstack -l 5296 > tdump_`date +%y%m%d`_`date +%H%M%S`.dump
sleep 2s
done

 

덤프파일 생성 후 간단한 분석은 위 사이트를 이용한다.