java - español - jcreator cannot find symbol
Problema de bloqueo de Java: ¿Por qué JVM bloquearía los subprocesos en muchas clases/métodos diferentes? (1)
Actualización: Esto parece un problema de memoria. Un archivo de 3.8 Gb Hprof indicaba que la JVM estaba descargando cuando se produjo este "bloqueo". Nuestro equipo de operaciones vio que el sitio no estaba respondiendo, tomó un seguimiento de la pila y luego cerró la instancia. Creo que cerraron el sitio antes de que terminara el basurero. El registro no tenía errores / excepciones / evidencia de problemas, probablemente porque la JVM se eliminó antes de que pudiera generar un mensaje de error.
Pregunta original Tuvimos una situación reciente en la que la aplicación apareció - para el usuario final - para colgar. Obtuvimos un seguimiento de pila antes del reinicio de la aplicación y encontré algunos resultados sorprendentes: de 527 subprocesos, 463 tenían el estado de subproceso BLOQUEADO.
En el pasado En el pasado, el subproceso bloqueado generalmente tenía este problema: 1) algún cuello de botella obvio: por ejemplo, un bloqueo de registro de la base de datos o un problema de bloqueo del sistema de archivos que causaba que otros subprocesos esperaran. 2) Todos los subprocesos bloqueados se bloquearían en la misma clase / método (por ejemplo, las clases de sistema de archivos o jdbc)
Datos inusuales En este caso, veo todo tipo de clases / métodos bloqueados, incluidas las clases internas jvm, las clases jboss, log4j, etc., además de las clases de aplicación (incluidas las llamadas jdbc y lucene)
La pregunta ¿qué causaría que una JVM bloquee log4j.Hierarchy.getLogger, java.lang.reflect.Constructor.newInstance? Obviamente algún recurso "es escaso" pero ¿qué recurso?
Gracias
será
Extractos de seguimiento de pila
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)
Estos se enumeran aproximadamente en el orden en que los probaría, según la evidencia recopilada:
- ¿Has mirado el comportamiento GC ? ¿Estás bajo presión de memoria? Eso podría resultar en el
newInstance()
denewInstance()
y algunos otros más. Ejecute su VM con-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -verbose:gc
y registre la salida. ¿Está viendo tiempos de GC excesivos cerca del tiempo de falla / bloqueo?- ¿Es la condición repetible ? Si es así, intente con diferentes tamaños de almacenamiento dinámico en la JVM (-Xmx) y vea si el comportamiento cambia sustancialmente. Si es así, busque pérdidas de memoria o dimensione adecuadamente el montón para su aplicación.
- Si lo anterior es difícil y no obtiene un
OutOfMemoryError
cuando debería hacerlo, puede ajustar los parámetros optimizables del GC ... consulte las opciones de JDK6.0 XX o el documento técnico de ajuste de JDK6.0 GC . Mire específicamente a-XX:+UseGCOverheadLimit
y-XX:+GCTimeLimit
y las opciones relacionadas. (tenga en cuenta que no están bien documentados, pero pueden ser útiles ...)
- ¿Podría haber un punto muerto ? Con solo extractos de seguimiento de pila, no se puede determinar aquí. Busque ciclos entre los estados del monitor en los que los subprocesos están bloqueados (frente a lo que contienen). Creo que
jconsole
puede hacer esto por usted ... ( sí, debajo de la pestaña de hilos, "detectar puntos muertos" ) - Intente hacer varios stacktraces repetidos y busque qué cambios y qué se mantiene igual ...
- Haga el análisis forense ... para cada entrada de la pila que dice "BLOQUEADO", vaya a buscar la línea específica del código y averigüe si hay un monitor allí o no. Si hay una adquisición real del monitor, debería ser bastante fácil identificar el recurso limitador. Sin embargo, algunos de sus hilos pueden aparecer bloqueados sin un monitor transparente disponible, estos serán más complicados ...