Teniendo en cuenta el Garbage Collector en Java

No pensaba yo que la tarea del garbage collector tomase demasiado tiempo o pudiese interferir en la ejecución de una aplicación Java. He leído el libro Java Programming Interviews Exposed que incluye un capítulo llamado Understanding the Java Virtual Machine en el que he aprendido cosas como que el proceso de garbage collection incluye una tarea de compactación para que los objetos que se usan conjuntamente estén cerca en memoria, lo que en arquitectura de computadores se explica como uno de los principios de localidad. En esta tarea de compactación también se intenta que toda la memoria libre esté consecutiva para evitar demasiados huecos.

Previo a la tarea de compactación el GC marca las zonas que la aplicación sigue referenciando como vivas y las que ha dejado de referenciar como muertas. Durante este proceso todos los hilos ejecutándose dentro de la máquina virtual se paran para evitar inconsistencias. A esto se le llama stop-the-world.

Para evitar que el GC entre en acción demasiadas veces durante la vida de la aplicación si ésta hace uso intensivo de la memoria parece necesario configurar adecuadamente los parámetros -Xms y -Xmx:

– El parámetro -Xms es el mínimo tamaño del heap y por defecto es 1/64 de la memoria total. Si la máquina es de 4 GB = 2^32 B, por defecto el espacio mínimo es de 64 MB.

– El parámetro -Xmx es el máximo tamaño del heap y por defecto es 1/4 de la memoria total.

while (condition()) {
 process() // Creates inside objects, between 1GB and 2GB of memory size
}

Para esta aplicación en la que se realizan varias iteraciones de un proceso que utiliza un rango de memoria entre 1 y 2 GB y para la siguiente iteración esta memoria ya no es necesaria, sería conveniente ejecutar la aplicación con -Xms2G y -Xmx2G porque de entrada la máquina virtual cuenta con el espacio de memoria suficiente para no tener que solicitar más al sistema operativo y porque el GC seguramente no recolectará espacio libre hasta que no haya terminado una iteración. Si se ejecuta entre iteración e iteración se puede dar el caso de que recolecte prácticamente los 2 GB de memoria que ha usado la iteración anterior y cuyos objetos ya no son necesarios más.

No hay que olvidar que la optimización se lleva a cabo una vez que se ha notado un rendimiento que no es óptimo y que se han encontrado los cuellos de botella. Jugar a ser adivinos pronosticando dónde ocurrirán los cuello de botella nos llevará a desarrollar aplicaciones complejas y pobres en rendimiento porque los cuellos de botella que aparezcan serán diferentes a los que se han intentado evitar.

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s