domingo, 11 de octubre de 2015

Java - Finalize y Garbage Collector: Los que nos salvan de colgarnos por memoria

En mi trabajo de grado tuve un problema relacionado con el manejo de memoria. En ese proyecto, enfocado en el análisis de cadenas, era imprescindible crear montones de objetos, analizarlos y obtener información a partir de ellos. Sabía que existía el Garbage Collector y que este era el encargado de liberar la memoria que dejaban todos mis objetos desreferenciados. Este es un ejemplo del mal uso de la memoria que a veces hacemos sin darle mucha importancia:


Es decir, cada que utilizamos y reutilizamos la misma variable para crear objetos de una clase, estamos dejando muchísimo trabajo al Garbage Collector, quien se encargará de liberar toda la memoria que ocupaban, por ejemplo, las 99 instancias anteriores de ObjetoPrueba.

Lo que no sabía hasta hace muy poco es que existe un método de la clase Object (y por lo tanto, de todas las clases Java) que es invocado por el Garbage Collector justo antes de que el objeto pase a mejor vida: el método finalize.

Supongamos que tenemos la definición de la siguiente clase (ObjetoPrueba) y el main ubicado en la clase Ejecutable:



Si ejecutamos este código podemos visualizar, como pocas veces pasa, cual es la labor del recolector de basura en tiempo real. El programa comienza creando instancias del ObjetoPrueba y justo cuando el Garbage Collector decide entrar al juego, se bajan de la memoria un numero crítico de instancias (la gran mayoría de ellas, donde ninguna esta referenciada), lo cual alivia la carga de memoria del sistema.

No es muy usual que dentro de un programa se utilice directamente el método finalize, pero es algo que puede llegar a ser muy interesante de experimentar si se trata de programas donde la creación de objetos es de vital importancia. Mas aún, si se tiene un programa donde la memoria es limitada y se cuenta con algoritmos de análisis de objetos, implementar y el método finalize puede llegar a ser una gran ventaja para el desarrollador.

En el momento de escribir estas lineas se me ocurre por ejemplo el poder determinar, en tiempo de ejecución, de cuales clases estamos creando una mayor cantidad de objetos que por algún motivo se quedan desreferenciados y solo cargan el sistema. Sabiendo eso se podría determinar cuales son clases críticas. Esto puede ser muy útil para que redefinamos los algoritmos que rodean a esa clase, o se cambie la implementación de la misma para que esto no suceda. Todo esto es con el fin de perfeccionar nuestras propias técnicas de desarrollo y así podamos generar programas más rápidos y eficientes.


No hay comentarios:

Publicar un comentario