Índice

Bloqueo Mutuo?

Bloqueos mutuos (interbloqueos) pueden ocurrir cuando dos o más hilos (subprocesos) están bloqueando los recursos en un orden que resulta que todos los subprocesos esperen indefinidamente.

El ejemplo más simple es cuando el Hilo A bloquea el Objeto A y luego intenta bloquear el Objeto B, mientras otro Hilo B tiene bloqueado Objeto B y está esperando para bloquear Objeto A. En este caso, el Hilo A nunca liberará al Objeto A porque está esperando por Objeto B. Esto nunca pasará porque el Hilo B mantendrá el Objeto B bloqueado indefinidamente mientras espera que el Objeto A esté disponible.

wrapper.check.deadlock

Compatibilidad :3.5.0
Ediciones :Edición ProfesionaEdición EstándarEdición de la Comunidad (No Compatible)
Plataformas :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/Linux

NOTA

Verificaciones de interbloqueos de hilos requieren que se use al menos Java versión 1.5. Máquinas JVM más antiguas ignorarán las verificaciones. Se puede detectar los interbloqueos envolviendo bloqueos de hilos basados en "monitor" (usando synchronized) a partir de Java 1.5. Interbloqueos envolviendo bloqueos de hilos "owned" or "reentrant" (usando ReentrantLock) también se pueden detectar a partir de Java 1.6.

Con Java 9, si una imagen de tiempo de ejecución personalizada no incluye el módulo java.management, las comprobaciones de interbloqueo se desactivarán.

La propiedad wrapper.check.deadlock, en combinación con las otras propiedades,

se usan para configurar como el Wrapper monitorea una JVM por hilos con bloqueos mutuos. Esto puede ser muy útil para detectar y luego solucionar problemas potencialmente fatales que de otro modo serían difíciles, si no imposibles, de solucionar.

Comprobar si existen interbloqueos es bastante rápido, pero implica bloquear brevemente y tomar una copia instantánea (snapshot) de todos los hilos, y por eso la propiedad se configura a FALSE por defecto.

Ejemplo: (Comprobar Deadlock: Off)
wrapper.check.deadlock=FALSE

Ejemplo Simple:

Lea los detalles de la propiedad a continuación, pero el siguiente ejemplo simple configurará el Wrapper para registrar la ubicación de un interbloqueo y luego reiniciar inmediatamente la JVM.

Ejemplo:
wrapper.check.deadlock=TRUE
wrapper.check.deadlock.interval=60
wrapper.check.deadlock.action=RESTART
wrapper.check.deadlock.output=FULL

wrapper.check.deadlock.interval

Compatibilidad :3.5.0
Ediciones :Edición ProfesionaEdición EstándarEdición de la Comunidad (No Compatible)
Plataformas :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/Linux

La propiedad wrapper.check.deadlock.interval permite controlar el intervalo en que el Wrapper buscará por bloqueos mutuos en una aplicación. Se puede configurar a cualquier intervalo, iniciando con ina vez por segundo, pero el valor predeterminado es "60" segundos (una vez por minuto). En general, para aplicaciones que se sabe que son estables, puede estar bien disminuir en gran medida la frecuencia de estas comprobaciones.

Ejemplo: (una vez a cada 60 segundos)
wrapper.check.deadlock.interval=60

wrapper.check.deadlock.action

Compatibilidad :3.5.0
Ediciones :Edición ProfesionaEdición EstándarEdición de la Comunidad (No Compatible)
Plataformas :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/Linux

La propiedad wrapper.check.deadlock.action permite controlar lo que hace el Wrapper cuando se detecta un interbloqueo. La acción predeterminada es RESTART.

Ejemplo:
wrapper.check.deadlock.action=RESTART

Las acciones posibles son:

  • DEBUG:

    hará que se registre un mensaje de depuración. Esto solamente es útil para ayudar a entender cuando se dispara una acción.

  • STATS (Desde ver. 3.5.52, ediciones Estándar / Profesional):

    imprimirá estadísticas de rendimiento.

  • DUMP:

    invocará un volcado de hilos.

  • GC (Desde ver. 3.5.7):

    invocará un barrido completo de recolección de basura en la JVM. Tenga en cuenta que hacer esto con frecuencia puede afectar el rendimiento de la JVM, ya que un barrido completo a menudo hará que todos los hilos se congelen durante la recolección de basura.

  • RESTART:

    detendrá la JVM actual y luego reiniciará una nueva invocación.

  • SHUTDOWN:

    detendrá la JVM y el Wrapper.

  • USER_<n> (Edición Profesional):

    disparará un evento definido por el usuario. Esto puede ser tanto el envío de un email o la ejecucuión de un comando de sistema externo. El comando podría ser cualquier cosa, desde realizar operaciones de limpieza a crear una trampa SNMP.

  • PAUSE:

    pausará la aplicación Java si la pausa está habilitada y la JVM se está ejecutando. Para más detalles, lea sobre la propiedad wrapper.pausable.

  • RESUME:

    reanudará la aplicación Java si está en estado de pausa. Esto se puede usar si la JVM no se detiene cuando está en pausa. Para más detalles, consulte la página de la propiedad wrapper.pausable.

  • SUSPEND_TIMEOUTS_<n> (Desde ver. 3.5.40, ediciones Estándar / Profesional):

    Indica al Wrapper que suspenda todos los tiempos de espera utilizados cuando la JVM no responde. <n> especifica el número de segundos para suspender los tiempos de espera, y debe ser en entre el rango 1-3600 (1h). Esto podría usarse si la aplicación Java necesita realizar una tarea de bloqueo larga y evitar que el Wrapper considere que la aplicación no responde.

    Los tiempos de espera también puede suspenderse por otras propiedades de ación, por el archivo de comandos o por el método WrapperManager.suspendTimeouts() de Java.

    Si se realizan varias solicitudes para suspender los tiempos de espera, el número de segundos especificado en cada solicitud no se somará. En cambio, el tiempo recién especificado reemplazará el tiempo de suspensión restante si es más largo y, de lo contrario, se ignorará.

  • RESUME_TIMEOUTS (Desde ver. 3.5.40, ediciones Estándar / Profesional):

    ordena al Wrapper que reanude todos los tiempos de espera suspendidos previamente.

    Los tiempos de espera también pueden reanudarse por otras propiedades de acción, por el archivo de comandos o por el método WrapperManager.resumeTimeouts() de Java.

  • SUCCESS (Desde ver. 3.5.5):

    ordena al Wrapper que restablezca su recuento interno de invocación fallidas y cuente la invocación actual como "exitosa". Esto probablemente no es útil en este contexto, pero está aqui por consistencia con otras propiedades.

  • NONE:

    ordena al Wrapper que registre el hecho que se ha detectado un interbloqueo, pero en realidad no hará nada.

NOTA

Tenga en cuenta que acciones que no reinician la JVM, como "NONE", se dispararán repetidamente cada vez que se realice la verificación de bloqueos mutuos.

Encadenamiento de Múltiples Acciones:

Es posible especificar más de una acción al separar las acciones con un espacio o una coma. Cuando se especifica más de una acción, dichas acciones se ejecutarán en rápida sucesión en el orden especificado.

El ejemplo siguiente realizará un volcado de hilos y luego reiniciará la JVM.

Ejemplo:
wrapper.check.deadlock.action=DUMP,RESTART

wrapper.check.deadlock.output

Compatibilidad :3.5.0
Ediciones :Edición ProfesionaEdición EstándarEdición de la Comunidad (No Compatible)
Plataformas :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/Linux

La propiedad wrapper.check.deadlock.output permite controlar qué información el Wrapper registrará al detectar un interbloqueo. El nivel de registro predeterminado es FULL.

Ejemplo:
wrapper.check.deadlock.output=FULL

Los niveles de registro de salida son:

  • FULL:

    hará que la clase WrapperManager dentro de la JVM registre un relatorio que incluye trazas de pila completas para los hilos involucrados en el interbloqueo.

    Ejemplo de Salida de "FULL":
    INFO   | jvm 1    | WrapperManager Error: Found 2 deadlocked threads!
    INFO   | jvm 1    | WrapperManager Error: =============================
    INFO   | jvm 1    | WrapperManager Error: "Locker-2" tid=18
    INFO   | jvm 1    | WrapperManager Error:   java.lang.Thread.State: BLOCKED
    INFO   | jvm 1    | WrapperManager Error:     at org.tanukisoftware.wrapper.test.DeadLock.lockSecond(DeadLock.java:64)
    INFO   | jvm 1    | WrapperManager Error:       - waiting on <0x000000002fcac6db> (a java.lang.Object) owned by "Locker-1" tid=17
    INFO   | jvm 1    | WrapperManager Error:     at org.tanukisoftware.wrapper.test.DeadLock.lockFirst(DeadLock.java:83)
    INFO   | jvm 1    | WrapperManager Error:       - locked <0x0000000029c56c60> (a java.lang.Object)
    INFO   | jvm 1    | WrapperManager Error:     at org.tanukisoftware.wrapper.test.DeadLock.access$100(DeadLock.java:22)
    INFO   | jvm 1    | WrapperManager Error:     at org.tanukisoftware.wrapper.test.DeadLock$1.run(DeadLock.java:42)
    INFO   | jvm 1    | WrapperManager Error:
    INFO   | jvm 1    | WrapperManager Error: "Locker-1" tid=17
    INFO   | jvm 1    | WrapperManager Error:   java.lang.Thread.State: BLOCKED
    INFO   | jvm 1    | WrapperManager Error:     at org.tanukisoftware.wrapper.test.DeadLock.lockSecond(DeadLock.java:64)
    INFO   | jvm 1    | WrapperManager Error:       - waiting on <0x0000000029c56c60> (a java.lang.Object) owned by "Locker-2" tid=18
    INFO   | jvm 1    | WrapperManager Error:     at org.tanukisoftware.wrapper.test.DeadLock.lockFirst(DeadLock.java:83)
    INFO   | jvm 1    | WrapperManager Error:       - locked <0x000000002fcac6db> (a java.lang.Object)
    INFO   | jvm 1    | WrapperManager Error:     at org.tanukisoftware.wrapper.test.DeadLock.access$100(DeadLock.java:22)
    INFO   | jvm 1    | WrapperManager Error:     at org.tanukisoftware.wrapper.test.DeadLock$1.run(DeadLock.java:42)
    INFO   | jvm 1    | WrapperManager Error:
    INFO   | jvm 1    | WrapperManager Error: =============================
    STATUS | wrapper  | A Thread Deadlock was detected in the JVM.  Restarting JVM.
    
  • SIMPLE:

    hará que la clase WrapperManager dentro de la JVM genere un informe que incluye solo un breve resumen nombrando los hilos y objetos involucrados en el interbloqueo. Esto es suficiente en muchos casos, especialmente para problemas conocidos.

    Ejemplo de Salida de "SIMPLE":
    INFO   | jvm 1    | WrapperManager Error: Found 2 deadlocked threads!
    INFO   | jvm 1    | WrapperManager Error: =============================
    INFO   | jvm 1    | WrapperManager Error: "Locker-2" BLOCKED waiting on a java.lang.Object owned by "Locker-1"
    INFO   | jvm 1    | WrapperManager Error: "Locker-1" BLOCKED waiting on a java.lang.Object owned by "Locker-2"
    INFO   | jvm 1    | WrapperManager Error: =============================
    STATUS | wrapper  | A Thread Deadlock was detected in the JVM.  Restarting JVM.
    
  • NONE (Desde ver. 3.5.16):

    hará que la clase WrapperManager dentro de la JVM suprima toda salida. Esto puede ser deseable para los sistemas de producción cuando se conoce un problema, pero no desea ni necesita mantener demasiada información en los registros. El proceso de Wrapper, como en las otras opciones, siempre registrará una entrada única para informar la razón por qué tiene lugar la acción activada.

    Ejemplo de Salida de "NONE":
    STATUS | wrapper  | A Thread Deadlock was detected in the JVM.  Restarting JVM.