Problème de blocage Java: pourquoi JVM bloquerait-elle les threads dans de nombreuses classes/méthodes différentes?

mise à Jour: Cela ressemble à un problème de mémoire. Un fichier HPROF de 3,8 Go indiquait que la JVM se déchargeait de son fardeau lorsque ce "blocage" s'est produit. Notre équipe opérationnelle a vu que le site ne répondait pas, a pris un traceur de pile, puis a éteint l'instance. Je crois qu'ils ont fermé le site avant la fin de la décharge. Le journal avait Non erreurs / exceptions/preuves de problèmes -- probablement parce que la JVM a été tuée avant qu'elle ne puisse générer une erreur message.

Question Initiale Nous avons eu récemment une situation où l'application est apparue --pour l'utilisateur final--à accrocher. Nous avons obtenu une trace de pile avant le redémarrage de l'application et j'ai trouvé des résultats surprenants: de 527 threads, 463 avaient l'état de thread bloqué.

dans le passé Dans le passé fil bloqué avait généralement ce problème: 1) un goulot d'étranglement évident: par exemple un problème de verrouillage d'enregistrement de base de données ou de système de fichiers les threads en attente. 2) Tous les threads bloqués seraient bloqués sur la même classe / méthode (par exemple les clases jdbc ou système de fichiers)

Données Inhabituelles Dans ce cas, je vois toutes sortes de classes/méthodes bloquées, y compris les classes internes jvm, les classes jboss, log4j, etc., en plus des classes d'application (y compris les appels jdbc et lucene)

la question ce qui causerait un blocage de log4j par une JVM.Hiérarchie.getLogger, Java.lang.refléter.Constructeur.newInstance? De toute évidence, une ressource "est rare", mais quelle ressource?

merci

sera

Trace De La Pile D'Extraits De

http-0.0.0.0-80-417" daemon prio=6 tid=0x000000000f6f1800 nid=0x1a00 waiting for monitor entry [0x000000002dd5d000]
   java.lang.Thread.State: BLOCKED (on object monitor)
                at sun.reflect.GeneratedConstructorAccessor68.newInstance(Unknown Source)
                at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
                at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
                at java.lang.Class.newInstance0(Class.java:355)
                at java.lang.Class.newInstance(Class.java:308)
                at org.jboss.ejb.Container.createBeanClassInstance(Container.java:630)

http-0.0.0.0-80-451" daemon prio=6 tid=0x000000000f184800 nid=0x14d4 waiting for monitor entry [0x000000003843d000]
   java.lang.Thread.State: BLOCKED (on object monitor)
                at java.lang.Class.getDeclaredMethods0(Native Method)
                at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)
                at java.lang.Class.getMethod0(Class.java:2670)

"http-0.0.0.0-80-449" daemon prio=6 tid=0x000000000f17d000 nid=0x2240 waiting for monitor entry [0x000000002fa5f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
                at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.register(Http11Protocol.java:638)
                - waiting to lock <0x00000007067515e8> (a org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler)
                at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.createProcessor(Http11Protocol.java:630)


"http-0.0.0.0-80-439" daemon prio=6 tid=0x000000000f701800 nid=0x1ed8 waiting for monitor entry [0x000000002f35b000]
   java.lang.Thread.State: BLOCKED (on object monitor)
                at org.apache.log4j.Hierarchy.getLogger(Hierarchy.java:261)
                at org.apache.log4j.Hierarchy.getLogger(Hierarchy.java:242)
                at org.apache.log4j.LogManager.getLogger(LogManager.java:198)
17
demandé sur user331465 2010-10-25 19:52:05

1 réponses

ceux-ci sont énumérés grossièrement dans l'ordre dans lequel je les jugerais, selon les preuves recueillies:

  • avez-vous regardé GC behavior ? Êtes-vous sous la pression de la mémoire? Cela pourrait entraîner le blocage de newInstance() et de quelques autres. Lancez votre VM avec -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -verbose:gc et enregistrez la sortie. Est-ce que vous voyez des temps de CG excessifs près de l'Heure de l'échec/verrouillage?
    • est la condition répétable ? Si c'est le cas, essayez de varier la taille des tas dans la JVM (-Xmx) et voyez si le comportement change substantiellement. Si c'est le cas, recherchez des fuites de mémoire ou de la taille correcte du tas pour votre application.
    • si le précédent est difficile, et que vous n'obtenez pas un OutOfMemoryError alors que vous devriez, vous pouvez accorder les accordables GC... voir JDK6.0 XX options , ou JDK6.0 GC according Whitepaper . Regardez spécifiquement -XX:+UseGCOverheadLimit et -XX:+GCTimeLimit et options connexes. (remarque: ces ne sont pas bien documentés, mais peut être utile...)
  • pourrait-il y avoir une impasse ? Avec seulement des extraits de trace de pile, ne peut pas déterminer ici. Recherchez les cycles parmi les états de l'écran où les threads sont bloqués (par rapport à ce qu'ils contiennent). Je crois que jconsole peut faire ça pour vous ... ( yep, sous l'onglet threads, "detect deadlocks" )
  • Essayer de faire plusieurs , a répété stacktraces et chercher ce qui change par rapport reste le même...
  • faire la criminalistique... pour chaque entrée de pile qui dit "bloqué", allez chercher la ligne de code spécifique et de comprendre s'il y a un moniteur là ou non. S'il y a une acquisition réelle de moniteur, il devrait être assez facile d'identifier la ressource limite. Cependant, certains de vos threads peuvent apparaître bloqués sans une transparence disponible moniteur, cela sera plus compliqué...
17
répondu andersoj 2015-03-04 10:43:30