2011-09-13 19 views
19

Sé que esto no es "mejor práctica" pero me gustaría saber si puedo Tomcat reinicio automático si mi aplicación desplegado una excepción OutOfMemory¿Puedo Tomcat reinicio automático JVM en excepción de memoria insuficiente

+0

La respuesta correcta es que los autores de Java nunca debería haber hecho OutOfMemoryErrors capturable. Siempre deberían matar a la VM, y un script o administrador manejaría el reinicio. Además, Tomcat no debería estar atrapando estos tampoco. – mikevdg

Respuesta

23

Usted puede tratar de utilizar la opción de JVM OnOutOfMemoryError

-XX:OnOutOfMemoryError="/yourscripts/tomcat-restart" 

También es posible generar el volcado del montón para su posterior análisis:

-XX:+HeapDumpOnOutOfMemoryError 

tener cuidado con la combinación de estas dos opciones. Si fuerza a matar el proceso en "tomcat-restart", el volcado del montón puede no estar completo.

+0

de hecho, me sale un error de PermGen debido a una fuga de cargador de clases supongo. Será el mismo trabajo de la bandera en ese escenario también? Sí – Abe

+2

, también funcionará para el error de espacio permgen. – Dan

+0

¿Pero cuál es el contenido de "tomcat-restart"? ¿Es solo shutdown.bat, startup.bat? – Gullbyrd

5

no es fácil , y definitivamente no a través de la JVM que acaba de sufrir la excepción de falta de memoria. Su mejor opción sería una combinación de monitor de estado tomcat junto con scripts cron o scripts de administrador de sistema programados relacionados; algo para verificar el estado del servidor y automáticamente detener y reiniciar el servicio si ha fallado.

+0

Parece que este es el consenso general ... :( – Abe

4

En general, no. La VM es un mal estado y no se puede confiar completamente en ella.

Normalmente, se puede usar un proceso de envoltura configurable que inicia y detiene la VM del servidor "real" que desee. Un ejemplo con el que he trabajado es "Java Service Wrapper" de Tanuki Software http://wrapper.tanukisoftware.com/doc/english/download.jsp

Sé que hay otros.

Para protegerse de los OOM en primer lugar, hay formas de instrumentar máquinas virtuales modernas mediante beans de interfaz para consultar el estado del montón y otras estructuras de memoria. Estos pueden usarse para, por ejemplo, advertir en un registro o un correo electrónico si algunas operaciones específicas de la aplicación están empujando algunos límites establecidos.

+1

envoltorio de Tanuki es definitivamente la mejor manera de ir –

+0

1 en mi caso el guión corrió como parte de la XX: OnOutOfMemoryError = "/ yourscripts/tomcat-reinicio no pudo llevar el gato de espalda hasta – Tomasz

+0

de Theres también YAJSW que dice ser totalmente compatible con JSW. es posible que desee darle una oportunidad si se adapta a sus necesidades (que es de código abierto), pero desde mi experiencia JSW vale la pena el precio. –

6

Sé que esto no es lo que ha preguntado, pero ¿ha intentado mirar a través de un vertedero para ver dónde puede estar perdiendo memoria?

Algunas herramientas muy útiles para la localización de fugas de memoria:

jdk/bin/jmap -histo:live pid 

Esto le dará un histograma de todos los objetos activos actualmente en la JVM. Busque cualquier recuento de objetos impares. Deberá conocer su aplicación bastante bien para poder determinar qué recuentos de objetos son impares.

jdk/bin/jmap -dump:live,file=heap.hprof pid 

Esto volcará todo el montón de la JVM identificada por pid. A continuación, puede utilizar el gran Eclipse Memory Analyzer para inspeccionarlo y descubrir quién se aferra a las referencias de sus objetos. Sus dos mejores amigos en Eclipse Memory Analyzer son el histograma y un right click -> references -> exclude weak/soft references para ver qué hace referencia a su objeto.

jconsole es, por supuesto, otra buena herramienta.

+0

Gracias por la hprof de comandos, es bueno tener en el arsenal ... :) yo uso VisualVM para este tipo de cosas normalmente. – Abe

0

¿Qué tal algo así? -XX:OnOutOfMemoryError="exec \`ps --no-heading -p $$ -o cmd\`"

1

Desafortunadamente cuando matas el proceso de java. Su secuencia de comandos mantendrá una referencia a los puertos tomcat 8080 8005 8009 y no podrá volver a iniciarla desde el mismo script. La única forma en que funciona para mí es:

-XX: OnOutOfMemoryError = "kill -9% p" y luego otro cron o monit o algo similar para asegurarse de tener el tomcat ejecutándose nuevamente.

% p es en realidad el pid JVM, algo que el JVM ofrece para usted.

Cuestiones relacionadas