Recolector de basuraEl recolector de basura de Sun llamado Garbage-First (conocido por el sobrenombre de G1) es el nuevo recolector de baja latencia que va a reemplazar a CMS en la máquina virtual Java Hotspot. G1 es un recolector del estilo servidor, pensado para máquinas multi-procesador con grandes cantidades de memoria.

Vamos a ver las caracteristicas destacadas de G1, un recolector que promete varios beneficios de rendimiento para los desarrolladores Java.

Lo destacado de G1

Hay dos grandes diferencias entre CMS (el recolector de basura actual) y G1.

La primera es que G1 es un recolector compactador. Compactar es un proceso por el cual los objetos vivos se mueven sobre la memoria libre hacia el final del heap de manera que se logra un área contigua de memoria libre. Esto es importante para las aplicaciones que se ejecutan por mucho tiempo porque es inevitable que el heap se fragmente con el paso del tiempo. G1 compacta lo suficiente para evitar completamente el uso de listas de reserva, lo cual simplifica considerablemente partes de la recolección y casi elimina por completo los potenciales problemas de la fragmentación.

Además de compactar, G1 ofrece una recolección de basura con pausas más predecibles que las obtenidas usando el recolector CMS, y le permite a los usuarios establecer las pausas deseadas. Este determinismo fuerte le brinda a G1 algunas características de un recolector de tiempo real. De todas formas, G1 no es un un recolector de tiempo real verdadero ya que existen factores (como el propio sistema operativo) que impiden que se puedan garantizar las pausas. Sin embargo G1 es considerablemente más facil de usar para los desarrolladores que los productos Java de tiempo real, ya que la base de código existente puede aprovechar un rendimiento mejorado sin necesidad de hacer cambios en el código.

G1 utiliza varias técnicas interesantes, basadas en información y métricas globales, para priorizar regiones de recolección de acuerdo a su eficiencia de recolección de basura.

Cómo funciona G1

Con G1, el heap se divide en regiones de tamaño fijo, y la separación entre la generación joven y madura de objetos es básicamente lógica. Algunas regiones se las considera jóvenes, algunas maduras. Todos los reclamos de espacio en G1 se hacen a través de copias. G1 selecciona un grupo de regiones, elije los objetos supervivientes de estas regiones y los copia a otro grupo de regiones. Así ocurre todo el reclamo de espacios en G1, en vez de usar la combinación de copia y de-asignación de espacio que hace CMS.

El primer objetivo de G1 es lograr pausas pequeñas de forma consistente en el tiempo. En esencia, como G1 compacta a medida que procede, copia objetos de un área del heap a otra. Entonces, debido a esta compactación, no tiene tantos problemas de fragmentación como CMS. Siempre va a haber área contiguas libres para reservar espacio, lo que permite que G1 tenga pausas consistentes en el tiempo.

El segundo objetivo de G1 es evitar lo más posible tener que hacer una recoleción de basura completa. Luego de que G1 realiza la fase de marca global que determina que tan vivos están los objetos en el heap, inmediatamente sabe en qué lugar del heap hay regiones casi vacias. G1 ataca primero esas regiones, dejando mucho espacio libre. De esta manera, el recolector de basura mantiene más espacio, disminuyendo la probabilidad de una recolección completa. Este es el motivo por el cual este recolector se llama Garbage-First (Basura-Primero).

El objetivo final es lograr una buena tasa de procesamiento. Para muchos usuarios, la tasa de procesamiento que logran sus aplicaciones es fundamental.

James Gosling sobre G1

En un podcast reciente, James Gosling destaca la importancia de G1 para ciertas aplicaciones Java de gran envergadura, como aplicaciones financieras, que se caracterizan por tener grandes cantidades de heap vivo y un nivel de paralelismo con threads considerable, y que suelen ejecutarse en grandes equipos con múltiples núcleos.

Gosling explica: "El gran secreto oculto de estas aplicaciones Java es que en realidad no utilizan bases de datos. En vez de bases de datos, estas aplicaciones usan enormes cantidades de RAM y utilizan al garbage collector a lo loco porque no pueden darse el lujo de usar el disco rígido. Cuando se están realizando miles y miles de transacciones por segundo es necesario mantener todo en la RAM, usando tablas de hash, y usar cuantos núcleos se pueda para enfocarse en la mayor cantidad de transacciones posible, y usualmente tienen grandes problemas con la latencia de las transacciones".

Gosling continua la charla explicando las concesiones que hay que hacer entre el procesamiento y el determinismo. Usualmente, los recolectores de basura están optimizados para uno o el otro. Un recolector de basura optimizado para el procesamiento suele ser útil para tareas como trabajos batch largos, en donde las pausas ocasionadas por el recolector de basura son menos problema que el completar todo el batch lo más rápido posible. En cambio, si estamos trabajando con un proceso interactivo como son las aplicaciones web, entonces un recolector de basura de baja latencia suele ser una mejor opción.

Gosling cuenta que estas conseciones también existen en otros lados de la JVM, y que en general la JVM está optimizada para el procesamiento. "Esto ocurre en cualquier lado donde existan algoritmos para reorganizar cualquier cosa. Por ejemplo, una tabla de hash - todos creen que una tabla de hash tiene un tiempo constante para insertar elementos y un tiempo constante para quitar elementos, pero esto es falso. El tiempo de inserción es constante hasta que se tenga que hacer un re-hash, y entonces esa inserción en particular va a llevar más tiempo".

G1 le permite a los usuarios especificarle al recolector de basura que no utilice más de x milisegundos de cualquier porción de tiempo de y milisegundos. Luego, G1 puede intentar mantener las pausas de recolección lo más pequeñas e infrecuentes como sea necesario para esa aplicación, pero no tan infrecuentes como para que disminuya el rendimiento. Dado que los recolectores de basura son una de las áreas en donde es más visible la consesión entre rendimiento y baja latencia, G1 va a brindar beneficios importantes a los desarrolladores Java.

Descargar G1

G1 ya está disponible como acceso temprano en Java 6 Update 14, y el equipo de de Hotspot de Sun está ansioso por recibir feedback y reporte de bugs de quienes comiencen a usarlo.

Más información en Garbage-First y Sun's Garbage-First collector largely eliminates low latency / high throughput tradeoff

Inspiración.

"Si tú tienes una manzana y yo tengo una manzana e intercambiamos las manzanas, entonces tanto tú como yo seguiremos teniendo una manzana cada uno. Pero si tú tienes una idea y yo tengo una idea, e intercambiamos las ideas, entonces ambos tendremos dos ideas"

Bernard Shaw