Eine meiner Anwendungen hängt unter einer gewissen Zeit unter Last. Weiß jemand, was eine solche Ausgabe in jstack verursachen könnte:
"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 oft in der jstack-Ausgabe, wenn sie hängt.
Ich benutze Spring @Async & Maps, synchronisierte Maps & Ehcache.
Interessant ist, dass dies nur auf einer der App-Instanzen geschieht. Zwei andere laufen einwandfrei. Was könnte ich sonst noch untersuchen, um in einem solchen Fall mehr Details zu erhalten?
Ich fand diesen Beitrag /programming/23992787/parking-to-wait-for-0xd8cf0070-a-java-util-concurrent-locks-abstractqueueds, aber er ist in meinem Fall nicht sehr nützlich.
waiting
wahrscheinlich die meiste Zeit sein wird. Du solltest woanders suchen. Das Warten hier verbraucht keine CPU und würde keine weiteren Leistungsprobleme verursachen.GC Overhead limit reached
. Dies ist ein klarer Hinweis darauf, dass Ihre App Speicherprobleme hat. Wenn Sie das sehen, bedeutet dies, dass die alte Generation ziemlich voll ist und nicht weiter GC-fähig ist.Antworten:
unsafe.park ist so ziemlich dasselbe wie thread.wait, außer dass es architekturspezifischen Code verwendet (daher der Grund, warum es "unsicher" ist). unsicher wird nicht öffentlich zugänglich gemacht, sondern in internen Java-Bibliotheken verwendet, in denen architekturspezifischer Code erhebliche Optimierungsvorteile bietet. Es wird häufig zum Thread-Pooling verwendet.
Um Ihre Frage zu beantworten, wartet der Thread nur auf etwas, er verwendet eigentlich keine CPU. In Anbetracht der Tatsache, dass Ihre ursprüngliche Stapelverfolgung zeigt, dass Sie eine Sperre verwenden, würde ich davon ausgehen, dass in Ihrem Fall ein Deadlock vorliegt.
Ja, ich weiß, dass Sie dieses Problem mit ziemlicher Sicherheit bereits gelöst haben. Sie sind jedoch eines der besten Ergebnisse, wenn jemand sun.misc.unsafe.park googelt. Ich denke, die Beantwortung der Frage kann anderen helfen, zu verstehen, was diese Methode ist, die anscheinend ihre gesamte CPU nutzt.
quelle
ExecutorService
ist und darauf wartet, dass eine Aufgabe über Methoden wie in die Arbeitswarteschlange gestellt wirdExecutorService.submit(...)
.Aus dem Stack-Trace geht hervor, dass der Thread ThreadPoolExecutor> Worker gestartet wurde und darauf wartet, dass die Aufgabe in der BlockingQueue (DelayedWorkQueue) verfügbar ist, um die Aufgabe auszuwählen und auszuführen. Dieser Thread befindet sich also nur im Status WAIT, solange a SIGNAL aus dem Publisher-Thread.
quelle
Ich hatte ein ähnliches Problem und nach den vorherigen Antworten (danke!) Konnte ich suchen und finden, wie ich mit der ThreadPoolExecutor-Terminierung richtig umgehen kann.
In meinem Fall behebt das nur meine fortschreitende Zunahme ähnlicher blockierter Threads:
ExecutorService::awaitTermination(x, TimeUnit)
undExecutorService::shutdownNow()
(falls erforderlich) in meiner finally-Klausel verwendet.Zur Information habe ich die folgenden Befehle verwendet, um die Anzahl der Threads 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
quelle