1. 개요
이 사용방법(예제)에서는 Java 응용 프로그램의 스레드 덤프를 캡처하는 다양한 방법에 대해 설명합니다.
스레드 덤프는 Java 프로세스의 모든 스레드 상태에 대한 스냅샷입니다 . 각 스레드의 상태는 스레드 스택의 내용을 보여주는 스택 추적으로 표시됩니다. 스레드 덤프는 스레드의 활동을 표시하므로 문제를 진단하는 데 유용합니다. 스레드 덤프는 일반 텍스트로 작성되므로 내용을 파일에 저장하고 나중에 텍스트 편집기에서 볼 수 있습니다 .
다음 섹션에서는 스레드 덤프를 생성하기 위한 여러 도구와 접근 방식을 살펴보겠습니다.
2. JDK 유틸리티 사용
JDK는 Java 애플리케이션의 스레드 덤프를 캡처할 수 있는 여러 유틸리티를 제공합니다. 모든 유틸리티는 JDK 홈 디렉토리 내의 bin 폴더 아래에 있습니다 . 따라서 이 디렉토리가 시스템 경로에 있는 한 명령줄에서 이러한 유틸리티를 실행할 수 있습니다.
2.1. 제이스택
jstack 은 스레드 덤프를 캡처하는 데 사용할 수 있는 명령줄 JDK 유틸리티입니다. 프로세스 의 pid 를 가져와서 콘솔에 스레드 덤프를 표시합니다. 또는 출력을 파일로 리디렉션할 수 있습니다.
jstack을 사용하여 스레드 덤프를 캡처하는 기본 명령 구문을 살펴보겠습니다.
jstack [-F] [-l] [-m] <pid>
모든 플래그는 선택 사항입니다. 그들이 의미하는 바를 보자:
- -F 옵션은 스레드 덤프를 강제 실행합니다. jstack pid 가 응답하지 않을 때 사용하기 편리합니다 (프로세스가 중단됨)
- -l 옵션은 유틸리티가 힙 및 잠금에서 소유 가능한 동기화 장치를 찾도록 지시합니다.
- -m 옵션 은 Java 스택 프레임 외에 기본 스택 프레임(C 및 C++)을 인쇄합니다.
스레드 덤프를 캡처하고 결과를 파일로 리디렉션하여 이 지식을 사용하도록 합시다.
jstack 17264 > /tmp/threaddump.txt
jps 명령 을 사용하여 Java 프로세스 의 pid 를 쉽게 얻을 수 있음을 기억하십시오 .
2.2. 자바 미션 컨트롤
JMC( Java Mission Control )는 Java 애플리케이션에서 데이터를 수집하고 분석하는 GUI 도구입니다. JMC를 실행하면 로컬 시스템에서 실행 중인 Java 프로세스 List이 표시됩니다. JMC를 통해 원격 Java 프로세스에 연결할 수도 있습니다.
프로세스를 마우스 오른쪽 버튼으로 클릭하고 " 비행 기록 시작 " 옵션을 클릭할 수 있습니다 . 그런 다음 스레드 탭에 스레드 덤프가 표시됩니다.
2.3. jvisualvm
jvisualvm 은 Java 애플리케이션을 모니터링, 문제 해결 및 프로파일링할 수 있는 그래픽 사용자 인터페이스가 있는 도구입니다 . GUI는 간단하지만 매우 직관적이고 사용하기 쉽습니다.
많은 옵션 중 하나를 사용하여 스레드 덤프를 캡처할 수 있습니다. Java 프로세스를 마우스 오른쪽 버튼으로 클릭하고 "스레드 덤프" 옵션을 선택하면 도구가 스레드 덤프를 만들고 새 탭에서 엽니다.
JDK 9부터 Visual VM은 Oracle JDK 및 Open JDK 배포판에 포함되어 있지 않습니다. 따라서 Java 9 이상 버전을 사용하는 경우 Visual VM 오픈 소스 프로젝트 사이트 에서 JVisualVM을 얻을 수 있습니다 .
2.4. jcmd
jcmd 는 JVM에 명령 요청을 보내 작동하는 도구입니다. 강력하지만 원격 기능이 포함되어 있지 않습니다 . Java 프로세스가 실행되는 동일한 시스템에서 사용해야 합니다.
많은 명령 중 하나는 Thread.print 입니다. 프로세스 의 pid 를 지정하여 스레드 덤프를 얻는 데 사용할 수 있습니다 .
jcmd 17264 Thread.print
2.5. 제이콘솔
jconsole을 사용하면 각 스레드의 스택 추적을 검사할 수 있습니다. jconsole 을 열고 실행 중인 Java 프로세스에 연결 하면 스레드 탭으로 이동하여 각 스레드의 스택 추적을 찾을 수 있습니다 .
2.6. 요약
따라서 JDK 유틸리티를 사용하여 스레드 덤프를 캡처하는 방법에는 여러 가지가 있습니다. 잠시 시간을 내어 각각에 대해 살펴보고 장단점을 간략히 살펴보겠습니다.
- jstack : 스레드 덤프를 캡처하는 가장 빠르고 쉬운 방법을 제공합니다. 그러나 Java 8부터 더 나은 대안을 사용할 수 있습니다.
- jmc : 향상된 JDK 프로파일링 및 진단 도구. 일반적으로 프로파일링 도구에서 문제인 성능 오버헤드를 최소화합니다.
- jvisualvm : 뛰어난 GUI 콘솔을 갖춘 경량의 오픈 소스 프로파일링 도구
- jcmd : 매우 강력하며 Java 8 이상에 권장됩니다. 스레드 덤프( jstack ), 힙 덤프( jmap ), 시스템 속성 및 명령줄 인수( jinfo ) 캡처 등 다양한 용도로 사용되는 단일 도구
- jconsole : 쓰레드 스택 트레이스 정보를 살펴보자
3. 명령줄에서
엔터프라이즈 애플리케이션 서버에서는 Security상의 이유로 JRE만 설치됩니다. 따라서 위에서 언급한 유틸리티는 JDK의 일부이므로 사용할 수 없습니다. 그러나 스레드 덤프를 쉽게 캡처할 수 있는 다양한 명령줄 대안이 있습니다.
3.1. kill -3 명령(Linux/Unix)
유닉스 계열 시스템에서 스레드 덤프를 캡처하는 가장 쉬운 방법 은 kill() 시스템 호출을 사용하여 프로세스에 신호를 보내는 데 사용할 수 있는 kill 명령을 사용하는 것 입니다. 이 사용 사례에서는 -3 신호를 보냅니다 .
이전 예제 의 동일한 pid 를 사용하여 kill 을 사용 하여 스레드 덤프를 캡처하는 방법을 살펴보겠습니다 .
kill -3 17264
이런 식으로 신호 수신 Java 프로세스는 표준 출력에 스레드 덤프를 인쇄합니다.
다음과 같은 튜닝 플래그 조합으로 Java 프로세스를 실행하면 스레드 덤프도 지정된 파일로 리디렉션됩니다.
-XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=~/jvm.log
이제 표준 출력 외에 -3 신호를 보내면 ~/jvm.log 파일 에서 덤프를 사용할 수 있습니다 .
3.2. Ctrl + Break(Windows)
Windows 운영 체제에서는 CTRL 및 Break 키 조합을 사용하여 스레드 덤프를 캡처할 수 있습니다 . 스레드 덤프를 가져오려면 Java 응용 프로그램을 시작하는 데 사용된 콘솔로 이동하고 Ctrl 키 와 Break 키를 함께 누릅니다 .
일부 키보드에서는 Break 키를 사용할 수 없습니다. 따라서 이러한 경우 CTRL , SHIFT 및 Pause 키를 함께 사용하여 스레드 덤프를 캡처할 수 있습니다 .
이 두 명령 모두 스레드 덤프를 콘솔에 인쇄합니다.
4. ThreadMxBean을 프로그래밍 방식으로 사용 하기
이 기사에서 논의할 마지막 접근 방식은 JMX를 사용하는 것 입니다. ThreadMxBean 을 사용 하여 스레드 덤프를 캡처합니다 . 코드로 보자:
private static String threadDump(boolean lockedMonitors, boolean lockedSynchronizers) {
StringBuffer threadDump = new StringBuffer(System.lineSeparator());
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
for(ThreadInfo threadInfo : threadMXBean.dumpAllThreads(lockedMonitors, lockedSynchronizers)) {
threadDump.append(threadInfo.toString());
}
return threadDump.toString();
}
위의 프로그램에서 우리는 여러 단계를 수행하고 있습니다:
- 처음에는 각 스레드의 스택 정보를 담기 위해 빈 StringBuffer 가 초기화됩니다.
- We then use the ManagementFactory class to get the instance of ThreadMxBean. A ManagementFactory is a factory class for getting managed beans for the Java platform. In addition, a ThreadMxBean is the management interface for the thread system of the JVM.
- Setting lockedMonitors and lockedSynchronizers values to true indicates to capture the ownable synchronizers and all locked monitors in the thread dump.
5. Conclusion
In this article, we've shown multiple ways to capture a thread dump.
At first, we discussed various JDK Utilities and then the command-line alternatives. In the last section, we concluded with the programmatic approach using JMX.