Domanda

Ho un servizio REST realizzato utilizzando Jersey .

Quando ho eseguito un " curl " contro la mia API REST, il comando si blocca.

Ho eseguito jstack & amp; questo è un output riassunto di due thread nello stato BLOCCATO.

"pool-2-thread-11" prio=6 tid=0x01d51800 nid=0x2394 
 waiting for monitor entry [0x05e6f000..0x05e6fce8]
java.lang.Thread.State: BLOCKED (on object monitor)
    at com.moi.DefaultImageProcessor$DownloadAndScaleCallable.call(
          DefaultImageProcessor.java:168)
    - waiting to lock <0x257aa440> 
     (com.moi.ImageUriMutexImpl$MutexImpl)
      at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
      at java.util.concurrent.FutureTask.run(FutureTask.java:138)
      at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
      at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
      at java.util.concurrent.FutureTask.run(FutureTask.java:138)
     at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(
        ThreadPoolExecutor.java:885)

"pool-2-thread-10" prio=6 tid=0x01d51000 nid=0x18d0
 waiting for monitor entry [0x05e1f000..0x05e1fd68]
java.lang.Thread.State: BLOCKED (on object monitor)
    at com.moi.DefaultImageProcessor$DownloadAndScaleCallable.call(
          DefaultImageProcessor.java:168)
    - waiting to lock <0x257aa6b8> 
     (com.moi.ImageUriMutexImpl$MutexImpl)
      at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
      at java.util.concurrent.FutureTask.run(FutureTask.java:138)
      at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
      at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
      at java.util.concurrent.FutureTask.run(FutureTask.java:138)
     at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(
        ThreadPoolExecutor.java:885)

Voglio sapere come leggere questo dump dello stack. Quali segni dovrei cercare in un punto morto?

AGGIORNAMENTO Ho risolto il mio problema! Fondamentalmente sto facendo un HttpClient 4.0 GET all'interno del blocco sincronizzato. HttpClient si stava comportando male & amp; non tornare & amp; si aggrappava alle serrature. Tramite jstack, c'erano un paio di thread che si aggrappavano ai blocchi che causavano il problema sopra. Ora capisco che non si trattava di deadlock così tanto, ma che i miei blocchi sincronizzati impiegavano troppo tempo per tornare.

È stato utile?

Soluzione

Dalla traccia dello stack piccolo i thread stanno solo aspettando di acquisire il blocco. Nella traccia cercare gli oggetti 0x257aa440 e 0x257aa6b8 e vedere chi ha bloccato quegli oggetti. Controlla se quel thread è bloccato.

In una situazione di deadlock vedresti un cerchio completo per gli stati bloccati. Prendi anche la traccia più volte per confermare se lo stato bloccato è momentaneo o una lunga attesa.

Altri suggerimenti

Dai un'occhiata a questa domanda . Questo è un estratto dello stacktrace che può essere generato:

"Thread-1" prio=10 tid=0x0841ac00 nid=0x77d waiting for monitor entry [0xb42bf000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at Deadlock$Friend.bowBack(Deadlock.java:16)
    - waiting to lock <0x8b80def8> (a Deadlock$Friend)
    at Deadlock$Friend.bow(Deadlock.java:13)
    - locked <0x8b80df08> (a Deadlock$Friend)
    at Deadlock$2.run(Deadlock.java:28)
    at java.lang.Thread.run(Thread.java:619)

"Thread-0" prio=10 tid=0x08419400 nid=0x77c waiting for monitor entry [0xb4310000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at Deadlock$Friend.bowBack(Deadlock.java:16)
    - waiting to lock <0x8b80df08> (a Deadlock$Friend)
    at Deadlock$Friend.bow(Deadlock.java:13)
    - locked <0x8b80def8> (a Deadlock$Friend)
    at Deadlock$1.run(Deadlock.java:25)
    at java.lang.Thread.run(Thread.java:619)



Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x083f1464 (object 0x8b80def8, a Deadlock$Friend),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x083efc90 (object 0x8b80df08, a Deadlock$Friend),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
    at Deadlock$Friend.bowBack(Deadlock.java:16)
    - waiting to lock <0x8b80def8> (a Deadlock$Friend)
    at Deadlock$Friend.bow(Deadlock.java:13)
    - locked <0x8b80df08> (a Deadlock$Friend)
    at Deadlock$2.run(Deadlock.java:28)
    at java.lang.Thread.run(Thread.java:619)
"Thread-0":
    at Deadlock$Friend.bowBack(Deadlock.java:16)
    - waiting to lock <0x8b80df08> (a Deadlock$Friend)
    at Deadlock$Friend.bow(Deadlock.java:13)
    - locked <0x8b80def8> (a Deadlock$Friend)
    at Deadlock$1.run(Deadlock.java:25)
    at java.lang.Thread.run(Thread.java:619)

Found 1 deadlock.

Quindi, quando hai un deadlock a portata di mano, la VM può rilevarlo e mostrarlo.

Dato che stai notando che il comando " si blocca " ;, e hai identificato due thread bloccati su un mutex ... direi che stai leggendo abbastanza bene i segni ...

Dipende davvero da cosa fa il tuo servizio. Cerca problemi di prestazioni e problemi di coerenza dei dati. Ad esempio, rimanere bloccati e non rispondere, o anche gravi cali delle prestazioni quando il volume delle richieste aumenta, è un buon segno che potresti avere un problema. Inoltre, i dati incoerenti tra più richieste (di nuovo, a seconda del servizio) possono anche indicare un problema.

Un deadlock (convenzionale) è facile da individuare con jstack - dirà che c'è un deadlock. (Ci possono essere casi in cui, ad esempio, i thread sono in attesa l'uno sull'altro ma non sull'altro blocco - EventQueue.invokeAndWait spesso causa questo.)

Quello che abbiamo qui sono due blocchi di thread che tentano di bloccare oggetti diversi (con i codici hash di identità 0x257aa440 e 0x257aa440). Probabilmente troverai altri thread che trattengono effettivamente questi blocchi (basta usare find nel tuo editor di testo). È possibile che il monitor sia stato rilasciato molto presto e non sia tenuto. In tal caso, probabilmente vedrai blocchi altamente contesi.

Questi sono due thread in conflitto per la stessa risorsa, quindi non è un problema. Potrebbe essere la metà del problema però.

Se questi due thread sono i soli bloccati, allora non sei in deadlock. Deadlock (nella sua forma più semplice) è il punto in cui due thread hanno già un lucchetto su due oggetti diversi, ma ognuno di essi desidera un lucchetto su quello degli altri.

Detto questo, proprio da quello che hai fornito, no non sei in un punto morto. Ma se le cose sono sospese e stanno iniziando a fare il backup, allora è una buona possibilità, ma è impossibile (o molto difficile almeno) dirlo con certezza solo da una discarica dello stack.

MODIFICA: Aspetta, non sono bloccati sulla stessa cosa. Ma entrambi i thread hanno la stessa funzione. Troverei improbabile che questo (da solo) ne causi uno, ma potrebbe far parte di un ciclo di thread che causa un deadlock.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top