2011-09-08 12 views
7

Duplicar posibles:
Catching java.lang.OutOfMemoryError¿Es una mala idea capturar OutOfMemoryError?

OutOfMemoryError son:

inicia cuando la Máquina Virtual de Java no puede asignar un objeto porque que está fuera de la memoria, y no más la memoria podría estar disponible en el recolector de basura

Java dice:

un error es una subclase de Throwable que indica problemas serios que una aplicación razonable no debe tratar de atrapar. La mayoría de estos errores son condiciones anormales.

Esto se siente como audiencia:

Si usted se está ahogando, ser razonable: no se debe tratar de nadar hacia arriba para mantener su cabeza fuera del agua. La muerte es típicamente el resultado de condiciones anormales.

Imaginemos un escenario donde se ejecuta un servicio. Por alguna razón, otra aplicación en el mismo servidor está consumiendo mucha memoria, causando un OOM inesperado en su servicio. ¿Es tan mala idea tratar de reducir el consumo de memoria de este servicio para permanecer disponible para el usuario?

¿O hay algo más fundamental que sucede en el nivel de JVM que impide la implementación de una solución de este tipo después de que se ha lanzado el OOM?

+0

@aix Pude cortar un par de referencias a algunas estructuras de datos al establecerlas como nulas incluso si no las guardé correctamente mientras todavía estaba bien con eso en situaciones dramáticas. – JVerstry

+0

@dogbane Su referencia no responde mi pregunta, esta pregunta no es un duplicado. – JVerstry

+0

Una mejor analogía sería: conducir un automóvil que se incendia. No intente continuar y llegar a su destino. Ponte del hombro duro. – Jim

Respuesta

0

El problema aquí es que OOM es un error que no debería ocurrir en circunstancias normales. Al atraparlo y tratar de liberar memoria, es probable que oculte algún tipo de fuga o comportamiento involuntario en otro lugar.

Si obtiene OOM, quizás sea porque no configuró la JVM para usar más memoria.

+0

Estoy de acuerdo, pero podría registrar ese problema después de liberar memoria y llamar al gc. No es imposible. – JVerstry

+1

Si puede solucionarlo, y sabe por qué ocurrió el error y era legítimo, entonces hágalo de todos modos. Pero la mayoría de las veces, cuando obtienes un OOM, no lo sabrás y será muy difícil recuperarlo porque verás que estás muy limitado en cuanto a lo que puedes hacer una vez que tu máquina virtual se haya quedado sin memoria. –

3

Como usted ha citado

inicia cuando la Máquina Virtual de Java no puede asignar un objeto porque que está fuera de la memoria, y no hay más memoria podrían estar disponibles por el colector basura

En ese punto, estás jodido. Esa descripción implica que Java/JVM no puede obtener suficientes recursos para operar, y si eso es cierto, la ejecución de más código Java para solucionar el problema sería en sí mismo problemático.

Una buena analogía es que su automóvil se ha quedado sin gasolina, y usted quiere arreglarlo pisando el acelerador.

Una solución mejor es hacer la planificación de capacidad y asegúrese

1) Sus servidores tienen suficiente memoria para realizar su trabajo
2) Los servicios que se ejecutan en los servidores realizan dentro de las especificaciones y no consumen más de una cierta cantidad de recursos.

+0

"JVM ya no se está ejecutando correctamente" o no tiene recursos para ejecutarse correctamente? – JVerstry

+0

realmente el segundo, editó mi respuesta. – hvgotcodes

+0

Eso es lo que estoy pensando también, por lo tanto, no sería completamente imposible o irrazonable (al menos) intentar salvar el día. – JVerstry

-1

Es una mala idea. Principalmente porque OutOfMemoryError es un Error no un Exception - Un error "indica problemas graves que una aplicación razonable no debe tratar de detectar".

En su lugar, analizar sus posibles escenarios y aplicar correcciones en base a la información proporcionada en este PDF

+1

Ok, pero ¿y si puede arreglar el avión para evitar el choque? ¿Hay alguna razón para no hacerlo? Esa es mi pregunta ... – JVerstry

+0

Hombre, ¡qué analogía! Por lo tanto, se produce un accidente de avión debido a alguna condición que la mayoría de las veces está fuera del control humano. Para eso, hay procedimientos de emergencia definidos para que aún algunas almas se puedan guardar. De manera similar, una aplicación debe tener una alerta temprana en su lugar si es tan crítica y debe tener un proceso de recuperación, si es razonable. Si está fuera para atrapar 'OutOfMemoryError', ¿dónde lo vería todo? y la mayoría de las veces cuando lo atrapa, no hay mucho que pueda hacer al respecto. Al igual que un avión que se estrelló en medio del Atlántico, incluso si tuvieras paracaídas, las posibilidades de sobrevivir son 0 –

-1

Es inútil. Porque en el momento en que se atrapa el error, es posible que esté tan corto de memoria que cualquier creación de objeto nuevo podría generar un nuevo OOME. Tener un margen de maniobra tan pequeño en la captura significa que la única acción que puede tomar es salir.

Prueba de este fragmento, y dime lo que su salida es:

 import java.util.LinkedList; 
     import java.util.List; 

     public class OOMErrorTest { 


     public static void main(String[] args) { 
      List<Long> ll = new LinkedList<Long>(); 

      try { 
       long l = 0; 
       while(true){ 
        ll.add(new Long(l++)); 
       } 
      } catch(OutOfMemoryError oome){   
       System.out.println("Error catched!!"); 
       System.out.println("size:" +ll.size()); 
      } 
      System.out.println("Test finished"); 
     } 

     } 

Pero estrictamente hablando, sí, estos son capturable.

+0

¿A qué te refieres al desintegrar con precisión? – JVerstry

+0

Me refiero a explotar. –

+1

Es posible que desee comprobar http://stackoverflow.com/questions/2679330/catching-java-lang-outofmemoryerror luego – JVerstry

-1

No puede realmente recuperarse de OOM. Sin embargo, hay una razón para intentar atrapar cualquier cosa: eso es lo que me dijo la facción "atrapable" cuando hicimos exactamente eso en un proyecto en el que ya no trabajo; esa es una de las razones: intente registrar lo que sucedió. Porque si no sabe qué sucedió, es difícil averiguar cómo hacer que el software vuelva a funcionar.

También hay un gran "pero" a esa única razón: no funcionará normalmente.

Normalmente, los errores no pueden repararse desde el código en ejecución, por eso existe esa diferencia.

Cuestiones relacionadas