Pergunta

Eu tenho um serviço REST construído usando Jersey .

Quando eu realizou uma "onda" contra a minha API REST, os trava de comando.

Eu corri jstack & esta é uma saída resumidos em dois tópicos no estado bloqueado.

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

Eu quero saber como ler este despejo de pilha. Que sinais eu deveria procurar em um impasse?

Atualizar Eu resolvi meu problema! Basicamente, eu estou fazendo um HttpClient 4.0 GET dentro do bloco sincronizado. O HttpClient estava se comportando mal e não retornando e ele segurou as fechaduras. Via jstack, houve um par de fios que prendem sobre a fechaduras que causaram o problema acima. Eu entendo agora que não foi impasses tanto, mas que meus blocos sincronizados foram levando muito tempo para retorno.

Foi útil?

Solução

Do pouco rastreamento de pilha os fios são apenas à espera de bloqueio de aquisição. No olhar de rastreio para os objetos 0x257aa440 e 0x257aa6b8 e ver que têm bloqueado esses objetos. Verifique se esse segmento está bloqueado.

Em situação de impasse você veria um círculo completo para os estados bloqueados. Também levar o traço várias vezes para confirmar se o estado bloqueado é momentânea ou uma longa espera.

Outras dicas

Dê uma olhada esta questão . Este é um trecho do stacktrace que pode ser gerada:

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

Então, quando você tem um impasse na mão da VM pode detectar e mostrá-lo.

Dado que você está percebendo que a "trava" de comando e de ter identificado dois tópicos bloqueados em um mutex ... Eu diria que você está lendo os sinais muito bem ...

É realmente depende do que o seu serviço faz. Procure problemas de desempenho e problemas de consistência de dados. Por exemplo, ficando preso e não responder, ou até mesmo sucessos de desempenho graves como o volume de pedidos sobem são bons sinais que você pode ter um problema. Além disso, os dados inconsistentes entre várias solicitações (novamente, dependendo do seu serviço) pode apontar para um problema também.

A (convencional) de impasse é fácil de detectar com jstack - ele vai dizer que há um impasse. (Pode haver casos em que, por exemplo, segmentos estão aguardando uns sobre os outros, mas não em cada um dos outros bloquear -. EventQueue.invokeAndWait muitas vezes faz isso)

O que temos aqui são dois blocos de threads que tentam bloquear objetos diferentes (com códigos de identidade de hash 0x257aa440 e 0x257aa440). Você provavelmente vai encontrar outros tópicos que realmente fazem prender esses bloqueios (basta usar encontrar em seu editor de texto). Pode ser o caso que o monitor foi lançado muito em breve antes e não é realizada. Nesse caso, você provavelmente está vendo fechaduras altamente sustentou.

Estes são dois tópicos em disputa para o mesmo recurso, de forma nenhuma isso em iself não é um problema. Pode ser metade do problema embora.

Se estes dois tópicos são os únicos one bloqueados, então você não está em um impasse. Impasse (na forma mais simples a sua) é onde duas threads cada já tem um bloqueio em dois objetos diferentes, mas cada um quer um bloqueio sobre os outros um.

Dito isso, apenas a partir do que você forneceu, não você não está em um impasse. Mas se as coisas estão pendurados, e começando a ficar apoiado, então é uma boa possibilidade, mas é impossível (ou pelo menos muito difícil) para dizer com certeza a partir de apenas um despejo de pilha.

EDIT: Espere, eles não são fixos na mesma coisa. Mas ambos os tópicos estão na mesma função. Eu acharia improvável que isso (sozinho) seria causando um, mas poderia parte de um loop de fios causando um impasse.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top