Solía pensar que no, pero ayer tuve que hacerlo. Es una aplicación que utiliza Akka (una implementación del sistema de actores para la JVM) para procesar trabajos asincrónicos. Uno de los actores realiza alguna manipulación de PDF, y debido a que la biblioteca tiene errores, muere con un de StackOverflowError
vez en cuando.
El segundo aspecto es que Akka está configurado para apagar todo su sistema de actores si se detecta algún error fatal de JVM (por ejemplo, StackOverflowError).
El tercer aspecto es que este sistema de actor está incrustado dentro de una aplicación web (por WTF-ish, legacy, razones), por lo que cuando el sistema de actor se cierra, la aplicación web no lo está. El efecto neto es que StackOverflowError
nuestra aplicación de procesamiento de trabajo se convierte en una aplicación web vacía.
Como una solución rápida, tuve que atrapar el StackOverflowError
lanzamiento, para que el grupo de hilos del sistema de actores no se derribara. Esto me lleva a pensar que tal vez a veces está bien detectar tales errores, especialmente en contextos como este. ¿Cuándo hay un grupo de subprocesos que procesa tareas arbitrarias? A diferencia de un, OutOfMemoryError
no puedo imaginar cómo StackOverflowError
puede dejar una aplicación en un estado inconsistente. La pila se borra después de tal error, por lo que el cálculo puede continuar normalmente. Pero tal vez me estoy perdiendo algo importante.
Además, tenga en cuenta que estoy dispuesto a corregir el error en primer lugar (de hecho, ya he arreglado un SOE en esta misma aplicación hace unos días), pero realmente no sé cuándo esto tipo de situación puede surgir.
¿Por qué sería mejor reiniciar el proceso JVM en lugar de detectarlo StackOverflowError
, marcar ese trabajo como fallido y continuar con mi negocio?
¿Hay alguna razón convincente para nunca atrapar a las empresas estatales? Excepto "mejores prácticas", que es un término vago que no me dice nada.
fuente
StackOverflowException
s generalmente se debe a una cadena de llamadas de método que no termina - aumentar el espacio de la pila aumentaría el costo de memoria de un nuevo subproceso sin ningún beneficio.:-)
Respuestas:
Como regla general, si nunca fuera absolutamente aceptable hacer algo, y hubiera un acuerdo al respecto, los implementadores del lenguaje no lo habrían permitido. Casi no hay tales máximas unánimemente claras. (Afortunadamente, ¡eso es lo que nos mantiene a los programadores humanos en trabajos!)
Parece que ha encontrado una situación en la que detectar este error es la mejor opción para usted: permite que su aplicación funcione, mientras que todas las demás alternativas no lo hacen, y eso es lo que cuenta al final. Todas las "mejores prácticas" son simples sumas de largas experiencias con muchos casos que generalmente se pueden usar en lugar de un análisis detallado de un caso específico para ahorrar tiempo; en su caso, ya realizó el análisis específico y obtuvo un resultado diferente. ¡Felicidades, eres capaz de pensar de forma independiente!
(Dicho esto, seguramente hay situaciones en las que un desbordamiento de la pila puede dejar una aplicación inconsistente al igual que un agotamiento de memoria. Imagine que se construye algún objeto y luego se inicializa con la ayuda de llamadas a métodos internos anidados; si uno de ellos arroja, el objeto puede muy bien estar en un estado que no se supone que sea posible, como si una asignación hubiera fallado. Pero eso no significa que su solución no pueda ser la mejor).
fuente
StackOverflowException
una excepción no detectable. Lo sé, es una plataforma diferente, pero pensé que podrían haber tenido una razón. Además, su punto con respecto a la inicialización de objetos es perfecto. Esto me lleva a pensar que debería captar este SOE algunas capas de abstracción a continuación, para no captar el SOE "incorrecto".situations here
debería sersituations where
.No sé si hay riesgos específicos de JVM aquí, pero en general parece bastante razonable.
Por ejemplo, existen algoritmos recursivos, como la selección rápida ingenua, que tienen una
log(n)
profundidad de pila en un caso típico, pero en el peor de los casos se degradan a una profundidadn
que puede hacer explotar la pila.El peor de los casos es raro, y es poco probable que vuelva a suceder si reinicia la ordenación en el conjunto parcialmente ordenado, por lo que tiene mucho sentido detectar una excepción de desbordamiento de pila cuando ocurre y reiniciar el trabajo en lugar de tratar de evitar que ocurra un error o mate Aplicación completa.
fuente