프로그램적으로 Thread Dump 를 얻는 방법
0. jstack 혹은 "kill -3" 을 이용하는 방법
다음과 같이 PID 를 얻는다.
ps -ef | grep java
JDK 내장 명령어는 다음과 같다.
jps -v
다음과 같이 Thread Dump 를 내보낸다.
kill -3 ${PID}
JDK 내장 명령어는 다음과 같다.
jstack -l -e ${PID}
JDK 7 혹은 JDK 8 은 "-e" 명령행 옵션이 없다.
kill -3
은 logs/catalina.out 으로 내보낸다.
표준출력으로 내보낸다. Ubuntu 에서 apt 명령어로 Apache Tomcat 을 설치했다면,
/var/log/syslog
로도 내보낸다.
사용하기는 jstack 이 편리하다. (전문적인 시스템 관리자가 있다면 그렇게 할 리가 없겠지만) 응용프로그램 로그가 logs/catalina.out 에 쌓인다면 더더욱 그렇다.
Apache Tomcat 이 응답하지 않아서,
그 원인을 분석하고자 하는 경우에는
프로그램적으로 Thread Dump 를 얻는 것은 의미 없는 일이고,
대부분 kill -3
이 사용된다.
1. java 코드
다음과 같이 하면 jstack 혹은 "kill -3" 을 사용하지 않고 프로그램적으로 Thread Dump 를 얻을 수 있다.
java.lang.management.ThreadMXBean tmb = java.lang.management.ManagementFactory.getThreadMXBean(); for (java.lang.management.ThreadInfo ti : tmb.dumpAllThreads(true, true)) { long threadId = ti.getThreadId(); String threadName = ti.getThreadName(); Thread.State threadState = ti.getThreadState(); String lockName = ti.getLockName(); StringBuffer stackTrace = new StringBuffer(); for (StackTraceElement ste : ti.getStackTrace()) { stackTrace.append(ste.toString()); stackTrace.append("\n"); } }
2. jsp 코드
jsp 에서는 다음과 같다.
<table> <thead> <tr> <th>ThreadId</th> <th>ThreadName</th> <th>ThreadState</th> <th>LockName</th> </tr> <tr> <th colspan="4">ThreadDump</th> </tr> </thead> <tbody> <% java.lang.management.ThreadMXBean tmb = java.lang.management.ManagementFactory.getThreadMXBean(); for (java.lang.management.ThreadInfo ti : tmb.dumpAllThreads(true, true)) { %> <tr> <td><%=ti.getThreadId()%></td> <td><%=ti.getThreadName()%></td> <td><%=ti.getThreadState()%></td> <td><%=ti.getLockName()%></td> </tr> <tr> <td colspan="4"><pre> <% for (StackTraceElement ste : ti.getStackTrace()) { out.println(ste.toString()); } %> </pre></td> </tr> <% } %> </tbody> </table>