TDA 설치 및 사용법(Thread Dump 분석)
Java 프로세스의 상태를 진단하는 세 가지 핵심 도구 중의 하나인 Thread Dump Analyzer(TDA)를 사용해서 Java Thread Dump을 분석하는 방법에 대해 알아보겠습니다.
- https://irockel.github.io/tda/ 사이트 접속하여 TDA를 다운로드합니다. 2026.4.6일 현재 TDA-3.0.tar이 가장 최신 버전입니다.

- 환경변수로 JAVA_HOME을 설정하지 않으신 분은 TDA-3.0.tar를 실행을 위해 아래와 같이 Batch 파일을 작성한 후 실행합니다. TDA-3.0.tar를 실행하기 위해서는 OpenJDK가 필요한 거 다 아시죠!
D:\tda> tda.bat @echo off setlocal :: 1. 로컬 JAVA_HOME 설정 (사용자님의 JDK 경로로 수정하세요) set "JAVA_HOME=D:\tda\jdk-26" set "PATH=%JAVA_HOME%\bin;%PATH%" :: 2. TDA 파일명 설정 (압축 해제 후 생성된 jar 파일명 확인) set "TDA_JAR=tda-3.0.jar" :: 3. TDA 실행 (메모리 1GB 할당, 백그라운드 실행) :: -Xmx1024m: 스레드 덤프 파일이 클 경우를 대비해 메모리를 넉넉히 잡았습니다. start "" java -Xmx1024m -jar "%TDA_JAR%" if %errorlevel% neq 0 ( echo [ERROR] TDA 실행에 실패했습니다. 경로와 자바 버전을 확인하세요. pause ) endlocal - 작성한 Batch 파일을 실행하면 아래와 같이 TDA 분석 도구가 실행됩니다. File > Open 메뉴 또는 Open Logfile…를 선택하여 Thread Dump 파일들을 불러옵니다. 시차를 두고 추출된 두 개 이상의 Thread Dump 파일을 불러와야 합니다.

- 불러온 두 개의 Thread Dump 파일을 선택하고, Tools > Find long running threads… 메뉴를 선택하여 오래 유지되는 Thread를 확인해 봅니다.


- 다른 기능의 사용법은 여기를 방문하여 확인해 보세요.
저희 회사는 Jeus7과 유물 버전의 Java(java version “1.7.0_80”)를 사용하고 있어서 Thread Dump 자동 생성 스크립트를 사용하여 Thread Dump를 관리/분석하고 있습니다.
$ vi checkThreadDump.sh
#!/bin/bash
# Registering crontab
# */10 /path/to/checkThreadDump.sh >> /path/to/checkThreadDump.log 2>&1
export JAVA_HOME="/usr/lib/jdk1.7.0_80"
export JEUS_HOME="/package/pmmhadm/jeus7"
export PATH=$JAVA_HOME/bin:$JEUS_HOME/bin:$PATH
[[ "$CURRENT_HOUR" > "1659" && "$CURRENT_HOUR" < "1705" ]] && > "/path/to/checkThreadDump.log"
# 1. Defining managed servers
SERVERS_WITH_PORTS=("PMMH:1134" "PMMI:1137" "PMMK:1152" "CSMD:1136")
echo "--- Thread Dump Collection Started at $(date) ---"
for ENTRY in "${SERVERS_WITH_PORTS[@]}"
do
SERVER_NAME="${ENTRY%%:*}"
SERVER_PORT="${ENTRY#*:}"
# 2. Checking log directories
LOG_DIR="/path/to/jeus7/logs/${SERVER_NAME}"
[ ! -d "$LOG_DIR" ] && mkdir -p "$LOG_DIR"
# 3. Checking the status of managed servers using dsa command
result=$(dsa <<EOF
si -state -server $SERVER_NAME
exit
EOF
)
echo "$result" | tail -3 | head -1 | grep -q RUNNING
IS_RUNNING=$?
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -m 10 "http://58.54.160.110:${SERVER_PORT}/index.html")
if [ $IS_RUNNING -ne 0 ] || [ "$HTTP_CODE" -ne 200 ]; then
echo " [ALERT] $SERVER_NAME Status: RUNNING($IS_RUNNING), HTTP($HTTP_CODE)"
# 4. Extract pid of managed server from jps -m command result
PID=$(jps -m | grep " -server $SERVER_NAME " | awk '{print $1}')
if [ -n "$PID" ]; then
# Creating two thread dump files at 5-second intervals
for i in 1 2 3
do
TIMESTAMP=$(date +%H%M%S)
DUMP_FILE="${LOG_DIR}/tda_${SERVER_NAME}_pid${PID}_seq${i}_${TIMESTAMP}.log"
echo " -> Generating Dump #$i for $SERVER_NAME (PID: $PID)"
echo " Path: $DUMP_FILE"
# Executing jstack command to create thread dump file
jstack $PID > "$DUMP_FILE"
# 5 second sleep
[ $i -ne 3 ] && sleep 5
done
else
echo " [SKIP] Could not find PID for $SERVER_NAME. (Process might be down)"
fi
else
echo " [SKIP] $SERVER_NAME is RUNNING."
fi
done
echo "--- Task Completed ---"
