2010-02-03 23 views
8

He escrito un programa java que necesita procesar miles de archivos de texto (todo debe cargarse en la memoria). Funciona bien con hasta 123 archivos de entrada, pero cuando lo ejecuto para procesar alrededor de 5000 archivos, termina inesperadamente en el medio de la carretera, sin dar ningún mensaje de error/excepción. ¿Alguien puede darme una pista sobre lo que podría haber salido mal?El programa Java termina inesperadamente sin ningún mensaje de error

Estoy usando jdk1.6 en Mac OS Leopard con 2GB de RAM.

+0

¿Qué tan grande son esos archivos (huella en la memoria)? ¿Has observado memoria libre con alguna herramienta? – lexu

+0

¿Cómo se determina que no se genera ningún mensaje de error o excepción? –

+0

Intente escribir algunos registros y encontrar dónde termina el programa cada vez, esto puede dar alguna pista sobre qué línea de código tiene el problema –

Respuesta

4

dado que es su programa, le sugiero que haga lo siguiente:

En primer lugar, cambiar el método de main por lo que todo se hace en un bloque try/catch que informa de todas las excepciones no capturadas; p.ej. algo como esto:

public static void main(String[] arghhhhh) { 
    try { 
     ... 
    } catch (Throwable ex) { 
     System.err.println("Uncaught exception - " + ex.getMessage()); 
     ex.printStackTrace(System.err); 
    } 
} 

En segundo lugar, busque cualquier lugar donde pueda "aplastar" las excepciones inesperadas al capturarlas y no informarlas.

En tercer lugar, busque en cualquier lugar que pueda llamar System.exit() en silencio. Esto también podría suceder en las bibliotecas ... si está utilizando una mal escrita.

Si estas medidas no le dan respuestas, tratar de averiguar cómo la aplicación está saliendo por

  • mediante la ejecución de un depurador con puntos de corte establecidos en los puntos clave, o
  • mediante la adición de declaraciones de impresión traza en puntos clave.
+0

gracias, intentaré esto ... – Fahim

+0

Sí, tengo el error OutOfMemory, que proviene de una función recursiva que atraviesa un árbol de 136600 nodos en orden. ¿Es debido a la recursión? ¿Debería intentar eliminar la recursión por bucle? ¿Es eso posible? – Fahim

+0

Dudo que la recursión (de un árbol de directorios de archivos) esté causando esto. Necesita utilizar un generador de perfiles de memoria para averiguar qué está usando la memoria. –

2

¿Está abriendo archivos simultáneamente? Es posible que se esté quedando sin memoria si está cargando demasiados archivos a la vez. Si los archivos son lo suficientemente grandes, es posible que se esté quedando sin memoria con solo un archivo abierto. Además, asegúrese de cerrar los archivos cuando haya terminado con ellos.

+0

La mayoría de los archivos tienen 4 KB de tamaño y el más grande es 193 KB. El tamaño de todos los archivos suma hasta 20 MB. Estoy leyendo esos archivos uno tras otro. Veo que se leyeron con éxito. Esos archivos, de hecho, proporcionan información a mi programa. No hago ningún cambio en los archivos. Mi programa aborta en el medio de procesar las entradas. Si se agota el montón, esperaría una excepción de memoria. Como no recibo ningún mensaje de error, no tengo ni idea. – Fahim

+0

* Cerré todos los archivos. * ¿Todavía no he visto memoria libre con ninguna herramienta? ¿Puedes sugerir alguna herramienta? – Fahim

1

Compruebe si tiene algún bloque try/catch que no registre las excepciones correctamente.

Lo más probable es que sea OutofmemoryError. Asegúrate de que la consola no sea redirigida.

+0

la consola no se redirige. – Fahim

3

Parece que está obteniendo OutofmemoryError.

si es el caso, intente aumentar el tamaño de la memoria dinámica.

java -Xms<initial heap size> -Xmx<maximum heap size> 
+1

Sí, tengo el error OutOfMemory, que proviene de una función recursiva que atraviesa un árbol de 136600 nodos en orden. ¿Es debido a la recursión? ¿Debería intentar eliminar la recursión por bucle? ¿Es eso posible? Sí, puedo aumentar el tamaño del montón, que considero que es la última opción. – Fahim

+0

¿cómo puedo verificar el tamaño del montón actual? ¿Tengo que aumentar el tamaño del montón antes de ejecutar mi programa? – Fahim

+0

Puede usar la utilidad JConsole que viene con JDK. –

0

Existen principalmente dos razones.

  1. Se ha producido un error del sistema "no administrado", es decir, java.lang.OutOfMemoryError.
  2. Se ha producido un error de aplicación "no controlada".
  3. Se ha llamado a System.exit.

Para hacer frente a estos escenarios consideran que hacer los siguientes pasos:

  • Look en su código para llamadas a System.exit.
  • Asegúrese de que maneja todas las excepciones en el marco de pila Java inicial, es decirPrincipal método:

    try { ..code } catch (Throwable t) {} t.printStackTrace

  • Asegúrese de que tiene el control, donde la stdout y stderr se dirige. Puede establecerlos programáticamente en archivos concretos:

System.setOut (nuevo PrintStream ("output.txt")); System.setErr (nuevo PrintStream ("err.txt"));

  • de inicio con argumentos como: -Xloggc: gc.log -XX: + PrintGCDetails -XX: + PrintGCTimeStamps
Cuestiones relacionadas