miércoles, julio 11, 2007

GC para tiempos bajos de respuesta (y II)

miércoles, julio 11, 2007 por Martín

Continuo y finalizo el post de ayer sobre recolección de basura en sistemas que necesitan tiempos rápidos de respuesta.

  1. Optimizar el tamaño de los TLABs : Esta es para nota. Un TLA (TLAB en Sun JDK, Jon Masamitsu escribió hace un año una excelente entrada sobre esto) es una zona de memoria en la que un thread tiene permiso exclusivo para acceder lo que significa que el thread puede reservar memoria sin ningún tipo de bloqueo por lo que el rendimiento es mayor.

    Configurar un tamaño adecuado de estos TLAs es algo complicado, de hecho se hace una tarea muy ardua sin una buena herramienta para controlar los cambios en el rendimiento, pero puede incrementar considerablemente el rendimiento.
  2. Ajustar el límite para la recolección de basura : Las recolecciones completas de basura no se realizan cuando el heap está lleno, ya que en ese momento se lanzaría una OutOfMemoryException, sino que se lanzan al llegar a un determinado límite. Las máquinas virtuales permiten cambiar ese límite.

    En ocasiones este límite puede ser demasiado bajo, y si realmente se conoce muy bien el funcionamiento de la aplicación se puede ajustar para que sea un poco mayor y de este modo quepan más objetos en memoria (con el consiguiente coste de recolección).
  3. Evitar la fragmentación y optimizar el ratio de compactación: Las máquinas virtuales sufren el mismo problema que la memoria física o los discos duros. El almacenamiento continuo de objetos crea fragmentación. Para solucionar esto, existe lo que se llama compactación. Periodicamente, con cada recolección de basura, la máquina virtual tratará de compactar algo del espacio del heap para que cojan más objetos.

    Las máquinas virtuales suelen ofrecer parámetros avanzados para configurar el modo en el que se compacta la memoria. Por ejemplo en JRockit es posible establecer el tanto por ciento de heap que se quiere compactar en cada recolección. Un porcentaje alto hará que se gaste mucho tiempo compactando, mientras que un porcentaje bajo puede incrementar demasiado la fragmentación, llegando incluso en el caso límite a provocar OutOfMemoryException cuando no hay más espacio para colocar objetos en memoria. Otra opción típica es en lugar de especificar el ratio de compactación sería especificar directamente el máximo número de objetos que pueden ser compactados en cada recolección de basura.
  4. Conocer el tamaño de los objetos: Conocer el tamaño de los objetos que la aplicación maneja también es importante. En un caso extremo, si se están almacenando objetos demasiado grandes, que no cojan en la young generation (e.g. enormes imágenes) irán directamente a parar a la old generation, incluso cuando se usen tan sólo temporalmente. En este caso, y si nuestra aplicación maneja frecuentemente este tipo de objetos, podemos caer en una situación en las recolecciones completas de basura sean muy frecuentes, o en la que simplemente obtengamos OutOfMemoryExceptions.

Bueno, más o menos estas son las cosillas que recogí en el análisis y que quizás a alguien le valgan. Dejo aquí unos enlaces con mucha más información y que he utilizado de fuente:

BEA JRockit configuration and tuning guide
BEA Memory Management Concepts Guide
IBM Garbage Collection Policies
Tuning Garbage Collection with the 5.0 Virtual Machine
Jon Masamitsu's Weblog

Si alguno tenéis alguna recomendación, añadido, corrección, etc., pues los comentarios son más que bien recibidos.

comments

0 Respuestas a "GC para tiempos bajos de respuesta (y II)"