intive Argentina Blog

Memory leaks

Los desarrolladores suelen pensar que el “Garbage collector” (GC) los libera completamente de la preocupación por la administración de memoria. Sin embargo, aunque el GC es muy eficiente en el manejo de la misma, muchas veces los desarrolladores terminan generando un memory leak. Un memory leak ocurre cuando las referencias a objetos que no son empleadas se mantienen de modo innecesario.

La detección de los memory leaks es muy difícil. Si bien existen herramientas que permiten visualizar el consumo de memoria, CPU, etc., éstas muestran sólo datos muy específicos, complejos de interpretar. A continuación, daremos más detalles sobre los Garbage collection roots y sus implicancias.

 

Garbage collection roots

Cuando un objeto puede ser referenciado por la aplicación, se lo considera “vivo”. Una vez que un objeto ya no es más referenciado y, por ende, no es alcanzado por el código de la aplicación, el GC lo remueve. Estos objetos, por su parte, forman parte de un árbol. Cada árbol de objetos tiene una o más raíces. Mientras la aplicación pueda acceder a todas las raíces, dicho árbol será accesible. Pero, ¿cuándo estos objetos raíz se consideran realmente accesibles? Existen objetos especiales, llamados Garbage collection roots, que están siempre al alcance.

Estos son los cuatro tipos de GC roots existentes:

  • Variables locales: se mantienen vivas por el stack del thread.
  • Thread activos: son siempre considerados objetos vivos, entonces, GC roots. Esto es especialmente importante para variables locales a los threads.
  • Variables estáticas: son referenciadas por sus clases, lo que hace que haya que considerarlas GC roots. Las clases pueden ser recolectadas por el garbage collector, que remueve las variables estáticas.
  • Referencias de tipo JNI: son objetos java que el código nativo ha creado como parte de un JNI call. Tienen un trato especial, ya que la JVM no conoce si los objetos están siendo apuntados por el código nativo.

al

 

Las causas de las memory leaks

Identificamos tres motivos de las memory leaks:

  • Mutable static fields and collection: Los campos estáticos nunca son limpiados por el GC. Las collection y variables estáticas suelen ser usadas para mantener una caché, o compartir estados entre Threads. Estos campos necesitan ser limpiados explícitamente. Si el programador no considera esto, nunca se limpiara, dando lugar a un memory leak.
  • Thread-Local variables: Una variable local del thread es un campo de la clase Thread. En aplicaciones multithread, cada instancia posee su propia instancia de X variable. Esto es de suma utilidad para mantener un estado del Thread, pero puede también ser peligroso, ya que estas variables locales no son removidas por el GC hasta que el thread finalice.
    Normalmente, los Thread son tratados como Pool de Thread, por lo que permanecen “vivos” por siempre y las variables locales no resultan removidas jamás.
  • Circular and complex Bi-Directional references: Se trata de problemas de memoria debidos a estructuras de objetos con muchas referencias, con las cuales los objetos no son removidos en caso de tener, al menos, una referencia establecida.

Solución

Un procedimiento sencillo (por lo visual, aunque algo grosero) para determinar si una aplicación contiene memory leaks, consiste en observar el perfil del consumo de memoria de la aplicación. Esta operación es sencilla si se emplea un profiler. Un profiler permite determinar, entre otras cosas (como el consumo de CPU), la memoria usada por la aplicación en tiempo real. A continuación dejamos algunos ejemplos y esperamos que el artículo les haya resultado explicativo:

NetBeans profiler: https://profiler.netbeans.org/
VisualVM: https://visualvm.java.net/
JProfiler: https://www.ej-technologies.com/products/jprofiler/overview.html

Lisandro Ronconi

Es desarrollador web en intive – FDV desde noviembre de 2014 e integrante de la Brigada Java. Es Analista Programador Universitario egresado de la Universidad Nacional de La Plata, donde en la actualidad cursa la Licenciatura en Informática. Además de trabajar y estudiar, en sus ratos libres, toca la guitarra.

Deja un comentario