Si no sabes que es un memory leak siéntete un afortunado, dado que estos nos hacen la vida imposible cuando suceden. Como sabrán java tiene un garbage collector o recolector de basura que se encarga de eliminar los objetos que no utilizamos y liberar la memoria.
Pero cómo sabe cuándo no usamos más un objeto? Una posibilidad es cuando nadie lo referencia. En el heap de la Máquina Virtual Java (JVM) guarda todos los objetos creados por la aplicación Java, por ejemplo, utilizando el operador "new". El recolector de basura de Java puede separar lógicamente el heap en diferentes áreas, por lo que el garbage collector puede rápidamente identificar los objetos que pueden quedar eliminados.
La memoria para los nuevos objetos se asigna en el heap en tiempo de ejecución. Las variables de instancia viven en el interior del objeto en el que se han declarado. Por lo tanto, si referenciamos siempre a un objeto por más que no lo usemos el garbage collector no lo va a poder eliminar. Si creamos objetos y no los liberamos nunca vamos a consumir cada vez más memoria y este es un recurso limitado por lo que tarde o temprano vamos a tener un OutOfMemoryError. Es decir nos, quedamos sin memoria.
Algo horrendo en la vida de un programador, es buscar este tipo de errores. Son muy difíciles de rastrear y muchas veces ocurren cuando la aplicación tiene tiempo corriendo.
Para ayudarnos a luchar contra los memory leak, eclipse creo MAT o The Eclipse Memory Analyze que es un rápido y seguro analizador de memoria java. ¿Que necesitamos para utilizarlo? Solamente un dump de memoria cuando ocurra el error. Si, si claro y ¿como obtengo esto?
Es muy fácil, para obtener un dump de memoria cuando ocurre un OutOfMemoryError debemos configurar la jvm con unos parámetros como lo indica la documentación de oracle:
-
-XX:-HeapDumpOnOutOfMemoryError que indica a la Jvm que haga un dump cuando ocurra un OutOfMemoryError
-
-XX:HeapDumpPath=./java_pid
.hprof que indica donde va a guardarse el dump, no es obligatorio pero es aconsejable configurar el path para estar seguros donde se va a guardar.
Por ejemplo con:
Java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/emanuelpeg/logs/
Le estoy diciendo a la jvm que guarde el dump de memoria en /home/emanuelpeg/logs/ cuando ocurra un OutOfMemoryError.
Luego de esto es todo muy fácil, solo tenemos que importar el dump a MAT y esta herramienta nos preguntará si queremos hacer un reporte con los memory leaks y simplemente tenemos que presionar finish para obtener un completo reporte interactivo de la memoria de la jvm.
A la vez nos brinda gráficos con los posibles errores, y contiene un histograma el cual muestra el número de instancias de una clase en particular y la cantidad de memoria que cada uno utiliza. Además, se puede agrupar por cargador de clase o paquete. Esto le permitirá centrarnos en nuestros objetos.
Como conclusión podemos asegurar que MAT es una herramienta indispensable para la búsqueda de memory leaks.
Más Información | MAT