java.lang.OutOfMemoryError: Java heap space

Hola a todos, tengo un problema al realizar una consulta muy grande a la base de datos( dos millones) desde mi aplicacion Java, me envia la siguiente exception: java.lang.OutOfMemoryError: Java heap space, investigue y muchos suguieren aumentar la memoria a la JVM, quisiera saber si alguien sabe como hacer esto de manera definitiva sin tener que hacerlo cada ves que ejecute mi aplicacion, de antemano muchas gracias.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

ups

joder si que es una buena cantidad de registros, usas el JTable para visualizar los datos? por que el JTable
a esa cantidad de registros empieza a tener problemas,

no uso jTables

Estoy trabajando con jsp y servlets, no estoy usando interfaces graficas swing. El problema se da cuando realizo esta consulta para generar un reporte(estoy utilizando iText para crear documentos pdf). De alguna forma ya lo pude solucionar mandando llamar el recolector de basura de manera manual, pero se tarda una eternidad pero ya no me manda la exception, si alguien sabe como aumentarle la memoria a la JVM para toda mi aplicacion de manera definitiva se lo agradeceria.

Imagen de ezamudio

JBoss, diseño

En JBoss editas el run.conf que viene en el directorio bin y le indicas la memoria que quieres asignarle. Pero si es comun que se hagan consultas que devuelven 2 millones de registros creo que lo mejor es que pienses en la manera de hacer esto por partes. Si es para presentarlo en una pagina, seguramente no vas a presentar los 2 millones de golpe sino que vas a paginar los resultados, por lo que no necesitas obtener TODOS los resultados si solamente vas a presentar digamos unos 100, asi que mejor haces el query agregando LIMIT y OFFSET al SQL para que solamente obtengas un subconjunto de los registros.
Si es para un reporte, pues si generas un excel tampoco te va a dejar meter mas de creo que 65mil registros (o 650mil tal vez pero dos millones seguro no entran). En caso de un PDF van a ser varias páginas asi que volvemos a lo mismo. No hay razón para tener que obtener 2 millones de registros de golpe; siempre vas a terminar trabajando con un subconjunto de eso. Asi que haz varios queries para ir obteniendo los datos y procesarlos. Qué vas a hacer cuando haya de repente 30 usuarios haciendo ese query? le van a poner 30GB de RAM al servidor?

Given the choice of dancing pigs and security, users will choose dancing pigs, every single time. - Steve Riley

Diseño de la aplicación

Seguramente podras encontrar eso en la especificacion de tu servidor y dependiendo de que estes usando puede variar, pero dejame decirte un par de cosas, a modo de comentario.

1.- No se como estes llamando al recolector de basura manualmente, pero seguramente es con alguna función como System.gc(), esto hace una llamada pero nada ni nadie te puede asegurar que el recolector realmente corra o en que momento lo hara.

2.- Como dicen los compañeros, dos millones de registros para una base de datos grande es algo aceptable y no dudo por nada que haya sistemas que generen esa cantidad de información en una consulta pero siendo realistas generar un reporte o presentarlo a una página es algo que no se ve muchas veces, yo recomiendo que uses un paginador, puedes manejar esa información pero imaginate que ella se trate de visualizar desde Internet, creo que este problema es cuestion de diseño mas de tu aplicacion mas que de Java.

Seguramente tu esperabas una respuesta respecto a aumentar la memoria de la maquina virtual, pero siempre busca una alternativa, maneja dos o mas opciones.

Saludos !!!