2009-12-11 27 views
8

Tengo un hilo en una aplicación web Java que causa un java.lang.OutOfMemoryError: excepción de espacio en montón Java, pero el bloque try/catch no capta el error.¿Por qué no se detecta "java.lang.OutOfMemoryError: espacio de almacenamiento dinámico de Java"?

Código de ejemplo:

private void doSomeWork() 
{ 
    try 
    { 
     processData(); //Causes OutOfMemoryError 
     System.out.println("This line does not execute"); 
    } 
    catch (Exception e) 
    { 
     System.out.println("Exception. This line does not execute."); 
     //Log error 
    } 
    finally 
    { 
     System.out.println("finally. This line does execute"); 
     System.out.println("Thread name: " + Thread.currentThread().getName()); 

    } 
} 

Salida:

 
finally. This line does execute 
Thread name: _Worker-8 
Exception in thread "_Worker-8" java.lang.OutOfMemoryError: Java heap space 
...

Antecedentes:

Hace poco se hizo cargo de este proyecto Java y estoy tratando de levantarse para acelerar con Java y este proyecto. Soy un desarrollador de C#, por lo que aún no estoy familiarizado con este proyecto o Java. Sé que puedo solucionar el error usando la configuración -Xmx, pero estoy interesado en detectar este error para poder registrarlo. El error no se muestra en ninguno de los archivos de registro, y la salida se muestra en la consola en modo de depuración en Eclipse.

Respuesta

39

Porque OutOfMemoryError es un Error, no un Exception. Como OutOfMemoryError no es una subclase de Exception, catch (Exception e) no se aplica.

OutOfMemoryError extiende Throwable, sin embargo, por lo que debería ser capaz de atraparlo. Aquí hay un SO discussion sobre cuándo (si alguna vez) debería detectar los errores. En general, dado que no puede hacer nada al respecto, la recomendación es no molestarse en detectar errores en el código de producción. Pero dado un caso especial en el que intentas solucionar lo que está pasando, podría ser útil.

+0

Agradable Respuesta con referencias de enlace. Lo aprecio, gracias! – Crispy

+2

Recomendaría atrapar throwables en la parte más externa de su aplicación (o en la parte más externa de un método de subproceso) para que pueda saber por qué su programa ha abortado (si no hay nadie más que lo haga por usted)) –

3

Un "~ Error" no es una "~ Excepción".

Tienes que coger "Error" o "Throwable"

2

OutOfMemoryError extiende VirtualMachineError mientras se extiende la excepción Throwable directamente. Por lo tanto, no está siendo capturado según las especificaciones de Java. SI está buscando captar todas las excepciones, agregue catch (Throwable e) a la cláusula y lo tendrá.

+0

para ser más precisos, OutOfMemoryError extiende VirtualMachineError, que extiende Error, y dado que los errores no son excepciones, una captura (Excepción) no puede detectarlo – chburd

+0

Bingo. Pensé en hacer una lista de todo el árbol, pero me puse perezoso :) – Daniil

11

java.lang.OutOfMemoryError no extiende java.lang.Exception por lo que no es una excepción. OutOfMemoryError extiende java.lang.Error. Si se desea capturar un error intente esto:

private void doSomeWork() 
{ 
    try 
    { 
     processData(); //Causes OutOfMemoryError 
     System.out.println("This line does not execute"); 
    } 
    catch (Error e) 
    { 
     System.out.println("Exception. This line does not execute."); 
     //Log error 
    } 
    finally 
    { 
     System.out.println("finally. This line does execute"); 
     System.out.println("Thread name: " + Thread.currentThread().getName()); 

    } 
} 

Nota: Excepción y Error extiende Throwable por lo que también se puede utilizar para atrapar tanto Throwable.

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Throwable.html

0

Lo que voy a hacer es añadir por lo general un 'UncaughtExceptionHandler' a un hilo por lo que si cualquier cosa fugas por lo menos tener la oportunidad de registrar el tema y tal vez hacer un poco de limpieza.

Cuestiones relacionadas