webentwicklung-frage-antwort-db.com.de

WAITING at Sun.misc.Unsafe.park (native Methode)

Eine meiner Anwendungen hängt sich während einer gewissen Zeit unter Last auf. Weiß jemand, was in jstack zu einer solchen Ausgabe führen kann?

"scheduler-5" prio=10 tid=0x00007f49481d0000 nid=0x2061 waiting on condition [0x00007f494e8d0000]
   Java.lang.Thread.State: WAITING (parking)
        at Sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000006ee117310> (a Java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at Java.util.concurrent.locks.LockSupport.park(LockSupport.Java:186)
        at Java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.Java:2043)
        at Java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.Java:1085)
        at Java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.Java:807)
        at Java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.Java:1043)
        at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1103)
        at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:603)
        at Java.lang.Thread.run(Thread.Java:722)

Ich sehe dies viel in Jstack-Ausgabe, wenn es hängt.

Ich benutze stark Spring @Async & Maps, synchronisierte Maps & ehcache.

Was interessant ist, geschieht dies nur auf einer der App-Instanzen. Zwei andere laufen einwandfrei. Was könnte ich sonst noch untersuchen, um in einem solchen Fall weitere Einzelheiten zu erfahren?

Ich fand diesen Beitrag https://stackoverflow.com/questions/23992787/parking-to-wait-for-0xd8cf0070-a-Java-util-concurrent-locks-abstractqueueds aber es ist nicht sehr nützlich in meinem Fall.

61
Konrad

unsafe.park ist so ziemlich dasselbe wie thread.wait, außer dass es architekturspezifischen Code verwendet (daher ist es 'unsicher'). unsafe wird nicht öffentlich zur Verfügung gestellt, sondern in Java internen Bibliotheken verwendet, in denen architekturspezifischer Code erhebliche Optimierungsvorteile bietet. Er wird häufig für das Thread-Pooling verwendet.

Zur Beantwortung Ihrer Frage wartet der Thread nur auf etwas, er benötigt also eigentlich keine CPU. In Anbetracht der Tatsache, dass Ihr ursprünglicher Stack-Trace anzeigt, dass Sie eine Sperre verwenden, würde ich annehmen, dass in Ihrem Fall eine Blockierung vorliegt.

Ja, ich weiß, dass Sie dieses Problem mit ziemlicher Sicherheit bereits gelöst haben. Sie sind jedoch eines der Top-Ergebnisse, wenn jemand Sun.misc.unsafe.park googelt. Ich nehme an, die Beantwortung der Frage kann anderen helfen, zu verstehen, was diese Methode zu sein scheint, die ihre gesamte CPU nutzt.

158
dsollen

Aus dem Stack-Trace geht hervor, dass der Thread ThreadPoolExecutor> Worker gestartet wurde und darauf wartet, dass die Task in der BlockingQueue (DelayedWorkQueue) verfügbar ist, um die Task auszuwählen und auszuführen SIGNAL aus dem Publisher-Thread.

6
Yoga Gowda

Ich hatte ein ähnliches Problem und konnte nach vorherigen Antworten (danke!) Suchen und herausfinden, wie ich mit dem ThreadPoolExecutor-Terminaison richtig umgehen kann.

In meinem Fall wird dadurch nur die fortschreitende Zunahme ähnlicher blockierter Threads behoben:

  • Ich habe ExecutorService::awaitTermination(x, TimeUnit) und ExecutorService::shutdownNow() (falls erforderlich) in meiner finally-Klausel verwendet.
  • Zur Information habe ich die folgenden Befehle verwendet, um Threadanzahl zu ermitteln und gesperrte Threads aufzulisten:

    ps -u javaAppuser -L | wc -l

    jcmd `ps -C Java -o pid =` Thread.print >> threadPrintDayA.log

    jcmd `ps -C Java -o pid =` Thread.print >> threadPrintDayAPlusOne.log

    cat threadPrint * .log | grep "pool-" | wc -l

1
boly38