Java Core: Sie können den Sicherheitspunkt nicht erreichen und hängen? !!

JVM-Hang-Case, bei dem kein Thread-Dump ausgegeben werden kann

Es ist nicht eindeutig zu bestimmen, was den Hang verursacht hat. Im Allgemeinen gibt Kill -QUIT für das Ereignis "JVM hung?" Keinen Thread-Dump oder Thread-Dump aus. Wird ausgegeben, aber die Antwort auf die Anfrage ist in das Phänomen unterteilt, dass sie nicht zurückgibt, egal wie lange Sie warten. `Dieser Beitrag beschreibt ein Muster, das auch keinen Thread-Dump ausgibt. `` Wenn ein Thread-Dump ausgegeben wird, Java auflegen? Bitte beziehen Sie sich auch darauf.

safepoint

Wenn die Java-VM einen Thread-Dump ausgibt oder einen vollständigen GC ausführt, werden alle derzeit ausgeführten Java-Threads an einem Speicherort verarbeitet, der als Sicherheitspunkt bezeichnet wird, und anschließend wird die gewünschte Operation ausgeführt. Wenn eine Java-VM hängt, weil sie keinen Thread-Dump ausgeben kann, kann dieser Sicherheitspunkt häufig nicht erreicht werden. Wenn Sie den Status einzelner Threads überprüfen, können Sie die Ursache ermitteln.

Überprüfen Sie SafepointStatus für jeden Java-Thread

Es tut mir leid für die Unannehmlichkeiten, aber ich habe ein GDB-Python-Skript erstellt, das den SafepointStatus für jeden JavaThread anzeigt. https://github.com/takimai39/gdb-java

Sehen Sie sich den Kern der hängenden JVM an

Lassen Sie uns den Code unter https://bugs.openjdk.java.net/browse/JDK-8064749 ausführen, um eine Situation zu erstellen, in der er tatsächlich hängt.

$ java -XX:-UseCompilerSafepoints Stuck
^Z
[1]+Stoppen Sie Java-XX:-UseCompilerSafepoints Stuck
$ kill -QUIT %1

[1]+Stoppen Sie Java-XX:-UseCompilerSafepoints Stuck
$ fg
java -XX:-UseCompilerSafepoints Stuck

Mit STRG + Z anhalten, kill -QUIT senden und mit fg zurückkehren, aber es wird kein Thread-Dump ausgespuckt. Holen Sie sich den Kern und überprüfen Sie den Status des Sicherheitspunkts.

$ jps
29617 Stuck
29657 Jps
$ gcore 29617
...
Saved corefile core.29617
$ gdb /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-11.b12.el7.x86_64/bin/java ./core.29617
...
(gdb) source sp.py
(gdb) safepoint
--------------------------------------------------------------------
Status:                 SafepointSynchronize::_synchronizing
waiting to block:       1
LWP     Java Thread Name        Status
--------------------------------------------------------------------
LWP 29618 DestroyJavaVM          ThreadSafepointState::_at_safepoint
LWP 29630 Timer                  ThreadSafepointState::_at_safepoint
LWP 29629 Worker                 ThreadSafepointState::_running
LWP 29627 Service Thread         ThreadSafepointState::_at_safepoint
LWP 29626 C1 CompilerThread1     ThreadSafepointState::_at_safepoint
LWP 29625 C2 CompilerThread0     ThreadSafepointState::_at_safepoint
LWP 29624 Signal Dispatcher      ThreadSafepointState::_at_safepoint
LWP 29623 ?                      ThreadSafepointState::_at_safepoint
LWP 29622 Reference Handler      ThreadSafepointState::_at_safepoint
(gdb)

SafepointSynchronize :: _state ist _synchronizing, daher versucht die JVM, alle JavaThreads in safepoint zu halten. Da das Warten auf das Blockieren jedoch 1 ist, hat ein Thread den Sicherheitspunkt noch nicht erreicht. Natürlich funktionieren JVM-Funktionen, die ebenfalls zum Sicherheitspunkt gehen müssen, wie z. B. Thread-Dumps, in dieser Situation nicht. In diesem Fall hängt der Thread am LWP 29629.

Überprüfen Sie den Stapel mit OpenJDK-Abwickler

https://qiita.com/takimai39/items/a78b7a64a501d77efed8 Lassen Sie uns den Stapel des Ziel-Threads (LWP 29629) mit diesem OpenJDK-Abwickler überprüfen.

(gdb) source dbg8.py
Installing openjdk unwinder
(gdb) source sp.py
(gdb) info thread
  Id   Target Id         Frame 
  14   Thread 0x7f373cd10700 (LWP 29630) 0x00007f3756e55945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
  13   Thread 0x7f373ce11700 (LWP 29629) 0x00007f3741109660 in ?? ()
  12   Thread 0x7f373cf12700 (LWP 29628) 0x00007f3756e55cf2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
  11   Thread 0x7f373d013700 (LWP 29627) 0x00007f3756e55945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
  10   Thread 0x7f373d114700 (LWP 29626) 0x00007f3756e55945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
  9    Thread 0x7f373d215700 (LWP 29625) 0x00007f3756e55945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
  8    Thread 0x7f373d316700 (LWP 29624) 0x00007f3756e55945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
  7    Thread 0x7f373d417700 (LWP 29623) 0x00007f3756e55945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
  6    Thread 0x7f373d518700 (LWP 29622) 0x00007f3756e55945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
  5    Thread 0x7f373d619700 (LWP 29621) 0x00007f375653ae47 in sched_yield () from /lib64/libc.so.6
  4    Thread 0x7f3740a02700 (LWP 29620) 0x00007f3756e55945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
  3    Thread 0x7f3740b03700 (LWP 29619) 0x00007f3756e55945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
  2    Thread 0x7f375726d700 (LWP 29618) 0x00007f3756e55945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
* 1    Thread 0x7f375726e740 (LWP 29617) 0x00007f3756e52f57 in pthread_join () from /lib64/libpthread.so.0
(gdb) thread 13
[Switching to thread 13 (Thread 0x7f373ce11700 (LWP 29629))]
#0  0x00007f3741109660 in ?? ()
(gdb) bt
#0  0x00007f3741109660 in [compiled offset=0x40] Stuck$Worker.run() () at Stuck.java:35
#1  0x00007f37410004e7 in StubRoutines (1) ()
#2  0x00007f3755b12b4a in JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*) (result=0x7f373ce10dc0, m=<optimized out>, args=<optimized out>, __the_thread__=0x7f37500ea800) at /usr/src/debug/java-1.8.0-openjdk-1.8.0.131-11.b12.el7.x86_64/openjdk/hotspot/src/share/vm/runtime/javaCalls.cpp:406
#3  0x00007f3755b0ffe4 in JavaCalls::call_virtual(JavaValue*, KlassHandle, Symbol*, Symbol*, JavaCallArguments*, Thread*) (__the_thread__=0x7f37500ea800, args=0x7f373ce10d30, method=<error reading variable: access outside bounds of object referenced via synthetic pointer>, result=0x7f373ce10dc0)
    at /usr/src/debug/java-1.8.0-openjdk-1.8.0.131-11.b12.el7.x86_64/openjdk/hotspot/src/share/vm/runtime/javaCalls.cpp:307
#4  0x00007f3755b0ffe4 in JavaCalls::call_virtual(JavaValue*, KlassHandle, Symbol*, Symbol*, JavaCallArguments*, Thread*) (result=result@entry=0x7f373ce10dc0, spec_klass=..., name=<optimized out>, signature=<optimized out>, args=args@entry=0x7f373ce10d30, __the_thread__=__the_thread__@entry=0x7f37500ea800)
    at /usr/src/debug/java-1.8.0-openjdk-1.8.0.131-11.b12.el7.x86_64/openjdk/hotspot/src/share/vm/runtime/javaCalls.cpp:204
#5  0x00007f3755b105f9 in JavaCalls::call_virtual(JavaValue*, Handle, KlassHandle, Symbol*, Symbol*, Thread*) (result=result@entry=0x7f373ce10dc0, receiver=..., spec_klass=..., name=<optimized out>, signature=<optimized out>, __the_thread__=__the_thread__@entry=0x7f37500ea800)
    at /usr/src/debug/java-1.8.0-openjdk-1.8.0.131-11.b12.el7.x86_64/openjdk/hotspot/src/share/vm/runtime/javaCalls.cpp:210
#6  0x00007f3755b55301 in thread_entry(JavaThread*, Thread*) (thread=<optimized out>, __the_thread__=0x7f37500ea800)
    at /usr/src/debug/java-1.8.0-openjdk-1.8.0.131-11.b12.el7.x86_64/openjdk/hotspot/src/share/vm/prims/jvm.cpp:2974
#7  0x00007f3755ef4c72 in JavaThread::thread_main_inner() (this=0x7f37500ea800)
    at /usr/src/debug/java-1.8.0-openjdk-1.8.0.131-11.b12.el7.x86_64/openjdk/hotspot/src/share/vm/runtime/thread.cpp:1710
#8  0x00007f3755d4be12 in java_start(Thread*) (thread=0x7f37500ea800)
    at /usr/src/debug/java-1.8.0-openjdk-1.8.0.131-11.b12.el7.x86_64/openjdk/hotspot/src/os/linux/vm/os_linux.cpp:790
#9  0x00007f3756e51e25 in start_thread () at /lib64/libpthread.so.0
#10 0x00007f375655634d in clone () at /lib64/libc.so.6
(gdb)

Frame # 0 ist die 35. Zeile von Stuck.java, eine enge Schleife mit while (), wie unten gezeigt. Es wurde von HotSpot in nativen Code kompiliert, weil es kompiliert heißt. Mit anderen Worten, es ist die Zieloperation, für die die Angabe von "-XX: -UseCompilerSafepoints" wirksam ist. (Standardmäßig ist es + UseCompilerSafepoints, sodass Sie wahrscheinlich nicht auf dieses Problem stoßen.)

 33         @Override
 34         public void run() {
 35             while (!isDone) { // <--Hier!
 36                 // burn
 37             }
 38         }

Im Fall eines JVM-Hangs, der keinen Thread-Dump ausgeben kann, ist es möglich, den Ursache-Thread zu finden und Inhalte zu verarbeiten, indem der Status des Sicherheitspunkts für jeden JavaThread auf diese Weise überprüft wird.

Recommended Posts

Java Core: Sie können den Sicherheitspunkt nicht erreichen und hängen? !!
Java auflegen?
Java und JavaScript
XXE und Java
Getter und Setter (Java)
[Java] Thread und ausführbar
Java wahr und falsch
[Java] Vergleich von Zeichenketten und && und ||
Java Core: gehackte Core-Datei
Java - Serialisierung und Deserialisierung
[Java] Argumente und Parameter
timedatectl und Java TimeZone
[Java] Verzweigen und Wiederholen
[Java] Variablen- und Typtypen
Java (Klasse und Instanz)
[Java] Überladen und überschreiben