web-dev-qa-db-fra.com

WAITING à Sun.misc.Unsafe.park (méthode native)

Une de mes applications se bloque sous une certaine période d’exécution sous charge, est-ce que quelqu'un sait ce qui pourrait provoquer une telle sortie dans jstack:

"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)

Je vois cela souvent dans la sortie jstack quand il se bloque.

J'utilise beaucoup Spring @Async & maps, des cartes synchronisées et ehcache.

Ce qui est intéressant cela ne se produit que sur l'une des instances d'application. Deux autres fonctionnent parfaitement bien. Sur quoi d'autre pourrais-je enquêter pour obtenir plus de détails dans un tel cas?

J'ai trouvé ce post https://stackoverflow.com/questions/23992787/parking-to-wait-for-0xd8cf0070-a-Java-util-concurrent-locks-abstractqueueds mais ce n'est pas très utile dans mon cas.

61
Konrad

unsafe.park est à peu près la même chose que thread.wait, à la différence qu’il utilise un code spécifique à l’architecture (ce qui explique pourquoi il est 'unsafe'). unsafe n’est pas rendu public, mais est utilisé dans Java bibliothèques internes où un code spécifique à l’architecture offrirait des avantages importants en termes d’optimisation. Il est beaucoup utilisé pour le pool de threads.

Donc, pour répondre à votre question, tout ce que le thread fait est en attente de quelque chose, il n’utilise pas vraiment de processeur. Étant donné que votre trace de pile d'origine montre que vous utilisez un verrou, je suppose qu'un blocage se produit dans votre cas.

Oui, je sais que vous avez presque certainement déjà résolu ce problème. Cependant, vous êtes l'un des meilleurs résultats si quelqu'un googe Sun.misc.unsafe.park. Je pense que répondre à la question peut aider les autres à essayer de comprendre quelle est cette méthode qui semble utiliser tout leur processeur.

158
dsollen

À partir de la trace de la pile, il est clair que le thread ThreadPoolExecutor> Worker a démarré et attend que la tâche soit disponible sur BlockingQueue (DelayedWorkQueue) pour sélectionner la tâche et s’exécuter. SIGNAL du fil d'éditeur.

6
Yoga Gowda

J'avais un problème similaire et suite aux réponses précédentes (merci!), J'ai pu chercher et trouver comment gérer correctement la terminaison ThreadPoolExecutor.

Dans mon cas, cela corrige simplement mon augmentation progressive de threads bloqués similaires:

  • J'ai utilisé ExecutorService::awaitTermination(x, TimeUnit) et ExecutorService::shutdownNow() (si nécessaire) dans ma clause finally.
  • Pour information, j'ai utilisé les commandes suivantes pour détecter le nombre de threads et répertorier les threads verrouillés:

    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