kill -3, aby uzyskać zrzut wątku Java


116

Używam kill -3polecenia, aby zobaczyć zrzut wątku maszyny JVM w systemie UNIX. Ale gdzie mogę znaleźć dane wyjściowe tego killpolecenia? Zgubiłem się!!


Który proces zabijasz? Czy jest to serwer aplikacji J2EE? W takim przypadku ślad stosu powinien znaleźć się na wyjściu standardowym.
Luciano Fiandesio


2
Nie powinienem tego pisać zrzutu wątku na konsoli. ponieważ klasa java ma konsolę jako std out
javanerd

Odpowiedzi:


194

Możesz alternatywnie użyć jstack (dołączony do JDK), aby wykonać zrzut wątku i zapisać wynik w dowolnym miejscu. Czy to nie jest dostępne w środowisku uniksowym?

jstack PID > outfile

1
Tak - w momencie uruchomienia. Możesz również określić -l (małą literę L), aby uzyskać długą listę, która drukuje dodatkowe informacje o blokadzie
Joshua McKinnon,

2
Dopóki komenda jstack nie powiedzie się konsekwentnie z powodu „Nie można wywnioskować typu wątku z adresu” ;-(
noahlz

1
Jeśli widzisz ten błąd, radzę skontaktować się z dostawcą. Szybkie wyszukiwanie pokazuje, na przykład, że w RHEL jest otwarty błąd dotyczący tego błędu i openjdk ...
Joshua McKinnon

7
Warto zauważyć, że jstack wymaga JDK. Jeśli uruchamiasz aplikacje na serwerze, na którym jest zainstalowane tylko środowisko JRE, musisz znaleźć inny sposób zrzucania wątków.
jeffkempf

1
Oto jak użyć jstacka, aby uzyskać zrzut wątku procesu działającego pod innym użytkownikiem, takim jak usługa Windows: stackoverflow.com/questions/1197912/ ...
Vadzim

44

Zrzut wątku jest zapisywany w systemie z maszyny wirtualnej, na której wykonano plik kill -3. Jeśli przekierowujesz dane wyjściowe konsoli JVM do pliku, zrzut wątku będzie znajdował się w tym pliku. Jeśli maszyna JVM działa w otwartej konsoli, zrzut wątku zostanie wyświetlony w jej konsoli.


1
Istnieje sposób na przekierowanie danych wyjściowych zrzutu wątków maszyny JVM do oddzielnego pliku. Zobacz w mojej odpowiedzi.
Vadzim

32

Istnieje sposób na przekierowanie wyjścia zrzutu wątku JVM w przypadku sygnału przerwania do oddzielnego pliku z opcją diagnostyczną LogVMOutput :

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

5
Technicznie rzecz biorąc, to nie „przekierowuje” wyjścia zrzutu wątku. Włącza logowanie JVM do jvm.log (co zawiera dane wyjściowe zrzutu wątku), ale kill -QUIT nadal będzie wykonywać zrzut na standardowe wyjście procesu (również). Głosowano za opisem niejasnych opcji JVM :)
sqweek

25

jcmdPreferowanym podejściem jest Java 8 na ilustracji .

jcmd <PID> Thread.print

Poniżej znajduje się fragment z dokumentacji Oracle :

Wydanie JDK 8 wprowadziło Java Mission Control, Java Flight Recorder i narzędzie jcmd do diagnozowania problemów z aplikacjami JVM i Java. Zaleca się użycie najnowszego narzędzia jcmd zamiast poprzedniego narzędzia jstack w celu ulepszenia diagnostyki i zmniejszenia narzutu wydajności.

Jednak wysyłanie tego z aplikacją może mieć konsekwencje licencyjne, których nie jestem pewien.


1
Niestety jcmdnie udaje się połączyć z procesem obsługi systemu Windows, com.sun.tools.attach.AttachNotSupportedException: Insufficient memory or insufficient privileges to attachpodczas gdy się jstack -Fudaje: stackoverflow.com/questions/1197912/ ...
Vadzim

1
Musisz uruchomić jcmd <pid> Thread.dump dla tego samego użytkownika co proces java, w przeciwnym razie twoje połączenia zostaną porzucone. Zobacz stackoverflow.com/questions/25438983/…
Twilite

11

W tej samej lokalizacji, w której znajduje się standardowe wyjście maszyny JVM. Jeśli masz serwer Tomcat, będzie to catalina_(date).outplik.


8

Używając kill -3, powinieneś zobaczyć zrzut wątku na standardowym wyjściu. Większość serwerów aplikacji zapisuje standardowe wyjście w oddzielnym pliku. Powinieneś go tam znaleźć, używając kill -3. Istnieje wiele sposobów uzyskiwania zrzutów wątków:

  • kill -3 <PID>: Daje wyjście na standardowe wyjście.
  • Jeśli ktoś ma dostęp do okna konsoli, w którym działa serwer, może użyć CtrlBreak kombinacji klawiszy + , aby wygenerować ślad stosu na STDOUT.
  • W przypadku maszyn wirtualnych typu hotspot możemy również użyć jstackpolecenia do wygenerowania zrzutu wątku. To część JDK. Składnia jest następująca:

    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]

Mam problem z użyciem Kill -3 <PID>. Działa poprawnie, ale zabija proces także po zapisaniu zrzutu wątku na konsolę. Czy ma to zrobić?
Ashley

@Ashley - no nie kill -3 <PID>powinno zabijać JVM. Jakiego typu aplikacji Java szukasz?
slm

2

W Jboss możesz wykonać następujące czynności

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

Spowoduje to przekierowanie wyjścia / zrzutu wątku do konsoli plików określonej w powyższym poleceniu.



2

Kroki, które należy wykonać, aby wykonać zrzut wątku samodzielnego procesu Java

Krok 1: Uzyskaj identyfikator procesu dla skryptu powłoki wywołującego program java

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

Krok 2: Uzyskaj identyfikator procesu dla dziecka, które zostało wywołane przez runABCD. Użyj powyższego PID, aby uzyskać childs.

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

Krok 3: Pobierz JSTACK dla konkretnego procesu. Uzyskaj identyfikator procesu swojego procesu XYSServer. tj. 8536

linux$ jstack **8536** > threadDump.log
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.