-3을 죽여 자바 스레드 덤프를 얻습니다.


116

kill -3UNIX에서 JVM의 스레드 덤프를 보려면 명령을 사용 하고 있습니다. 그러나이 kill명령 의 출력은 어디에서 찾을 수 있습니까? 나는 길을 잃었다 !!


어떤 프로세스를 죽이고 있습니까? J2EE 앱 서버입니까? 이 경우 표준 출력에서 ​​스택 추적을 찾아야합니다.
Luciano Fiandesio

나는 자바 클래스를 실행하는 프로세스를 죽이고있다
javanerd

2
콘솔에 스레드 덤프를 쓰면 안됩니다. 자바 클래스는 표준 출력으로 콘솔이 있기 때문에
javanerd

답변:


194

또는 jstack (JDK에 포함됨)을 사용하여 스레드 덤프를 가져와 원하는 곳에 출력을 작성할 수 있습니다. 유닉스 환경에서는 사용할 수 없습니까?

jstack PID > outfile

1
예-실행되는 시점에. 또한 긴 목록이 인쇄 추가 잠금 정보 (소문자 L) -l을 지정할 수 있습니다
여호수아 맥키에게

2
jstack 명령이 "주소에서 스레드 유형을 추론 할 수 없음"으로 인해 계속 실패 할 때까지 ;-(
noahlz

1
해당 오류가 표시되는 경우 공급 업체에 문의하는 것이 좋습니다. 예를 들어 빠른 검색은이 오류 및 openjdk와 관련하여 RHEL에 열린 버그가 있음을 보여줍니다.
Joshua McKinnon 2011

7
jstack에 JDK가 필요하다는 점은 주목할 가치가 있습니다. JRE 만 설치된 서버에서 앱을 실행하는 경우 스레드 덤프를위한 다른 방법을 찾아야합니다.
jeffkempf

1
다음은 jstack을 사용하여 Windows 서비스와 같은 다른 사용자에서 실행중인 프로세스의 스레드 덤프를 얻는 방법입니다. stackoverflow.com/questions/1197912/…
Vadzim

44

스레드 덤프는 .NET Framework를 실행 한 VM의 시스템에 기록됩니다 kill -3. JVM의 콘솔 출력을 파일로 리디렉션하는 경우 스레드 덤프가 해당 파일에 있습니다. JVM이 열린 콘솔에서 실행중인 경우 스레드 덤프가 콘솔에 표시됩니다.


1
JVM 스레드 덤프 출력을 별도의 파일로 리디렉션하는 방법이 있습니다. 내 대답을 참조하십시오.
Vadzim

32

중단 신호의 JVM 스레드 덤프 출력을 LogVMOutput 진단 옵션을 사용하여 별도의 파일로 리디렉션하는 방법이 있습니다 .

-XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=jvm.log

5
기술적으로 이것은 스레드 덤프 출력을 "리디렉션"하지 않습니다. jvm.log (스레드 덤프 출력 포함)에 JVM 로깅을 설정하지만 kill -QUIT는 여전히 프로세스의 stdout에 덤프합니다 (또한). 모호한 JVM 옵션에 대한 설명에 대한 찬성 :)
sqweek

25

그림에서 Java 8을 사용 jcmd하는 것이 선호되는 접근 방식입니다.

jcmd <PID> Thread.print

다음은 Oracle 문서 의 스 니펫입니다 .

JDK 8 릴리스에는 JVM 및 Java 애플리케이션의 문제를 진단하기위한 Java Mission Control, Java Flight Recorder 및 jcmd 유틸리티가 도입되었습니다. 향상된 진단 및 성능 오버 헤드 감소를 위해 이전 jstack 유틸리티 대신 최신 유틸리티 인 jcmd를 사용하는 것이 좋습니다.

그러나 이것을 응용 프로그램과 함께 제공하면 라이선스에 영향을 미칠 수 있지만 확실하지 않습니다.


1
불행히도 jcmd와 윈도우 서비스 프로세스에 연결하는 데 실패 com.sun.tools.attach.AttachNotSupportedException: Insufficient memory or insufficient privileges to attach하면서이 jstack -F성공 : stackoverflow.com/questions/1197912/...
바드

1
Java 프로세스와 동일한 사용자로 jcmd <pid> Thread.dump를 실행해야합니다. 그렇지 않으면 연결이 끊어집니다. 참조 stackoverflow.com/questions/25438983/…
Twilite

11

JVM의 stdout이있는 동일한 위치에 있습니다. Tomcat 서버가있는 경우 이것이 catalina_(date).out파일 이됩니다 .


8

kill -3을 사용하면 표준 출력에서 ​​스레드 덤프를 볼 수 있습니다. 대부분의 애플리케이션 서버는 표준 출력을 별도의 파일에 기록합니다. kill -3을 사용할 때 찾을 수 있습니다. 스레드 덤프를 가져 오는 방법에는 여러 가지가 있습니다.

  • kill -3 <PID>: 표준 출력으로 출력합니다.
  • 서버가 실행중인 콘솔 창에 액세스 할 수있는 경우 Ctrl+Break 키 조합을 사용하여 STDOUT에서 스택 추적을 생성 .
  • 핫스팟 VM의 경우 jstack명령을 사용하여 스레드 덤프를 생성 할 수도 있습니다 . JDK의 일부입니다. 구문은 다음과 같습니다.

    Usage:
    
    jstack [-l] <pid> (to connect to running process)
    jstack -F [-m] [-l] <pid>(to connect to a hung process)
    
     - For JRockit JVM we can use JRCMD command which comes with JDK Syntax: 
       jrcmd <jrockit pid> [<command> [<arguments>]] [-l] [-f file] [-p] -h]

Kill -3 <PID>를 사용하는 데 문제가 있습니다. 정상적으로 작동하지만 스레드 덤프를 콘솔에 쓴 후에도 프로세스를 종료합니다. 그렇게해야하나요?
Ashley

@Ashley- kill -3 <PID>JVM을 죽여서는 안됩니다. 어떤 유형의 Java 앱을보고 있습니까?
slm

2

Jboss에서는 다음을 수행 할 수 있습니다.

nohup $JBOSS_HOME/bin/run.sh -c  yourinstancename $JBOSS_OPTS >> console-$(date +%Y%m%d).out  2>&1 < /dev/null &
kill -3 <java_pid>

그러면 출력 / threadump가 위의 명령에 지정된 파일 콘솔로 리디렉션됩니다.



2

독립 실행 형 Java 프로세스의 스레드 덤프를 원하는 경우 따라야하는 단계

1 단계 : Java 프로그램을 호출하는 쉘 스크립트에 대한 프로세스 ID 가져 오기

linux$ ps -aef | grep "runABCD"

user1  **8535**  4369   0   Mar 25 ?           0:00 /bin/csh /home/user1/runABCD.sh

user1 17796 17372   0 08:15:41 pts/49      0:00 grep runABCD

2 단계 : runABCD에 의해 호출 된 하위에 대한 프로세스 ID를 가져옵니다. 위의 PID를 사용하여 자식을 가져옵니다.

linux$ ps -aef | grep **8535**

user1  **8536**  8535   0   Mar 25 ?         126:38 /apps/java/jdk/sun4/SunOS5/1.6.0_16/bin/java -cp /home/user1/XYZServer

user1  8535  4369   0   Mar 25 ?           0:00 /bin/csh /home/user1/runABCD.sh

user1 17977 17372   0 08:15:49 pts/49      0:00 grep 8535

3 단계 : 특정 프로세스에 대한 JSTACK을 가져옵니다. XYSServer 프로세스의 프로세스 ID를 가져옵니다. 즉 8536

linux$ jstack **8536** > threadDump.log
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.