Una de las ventajas más importantes de Java es su gestión de memoria. Simplemente crea objetos y Java Garbage Collector se encarga de asignar y liberar memoria. Sin embargo, la situación no es tan simple, porque las pérdidas de memoria ocurren con frecuencia en las aplicaciones Java.
Este tutorial ilustra qué es la pérdida de memoria, por qué ocurre y cómo prevenirla.
1. ¿Qué es la pérdida de memoria?
Definicion de Pérdida de memoria: la aplicación ya no utiliza los objetos, pero Garbage Collector no puede eliminarlos porque se hace referencia a ellos.
Para comprender esta definición, necesitamos comprender el estado de los objetos en la memoria. El siguiente diagrama ilustra lo que no se usa y lo que no se hace referencia.
Del diagrama, hay objetos referenciados y objetos sin referencia. Los objetos sin referencia serán recolectados como basura, mientras que los objetos referenciados no serán recolectados como basura. Los objetos no referenciados seguramente no se utilizan, porque ningún otro objeto se refiere a ellos. Sin embargo, no todos los objetos no utilizados están sin referencia. ¡Algunos de ellos están siendo referenciados! De ahí es de donde vienen las pérdidas de memoria.
2. ¿Por qué ocurren las pérdidas de memoria?
Echemos un vistazo al siguiente ejemplo y veamos por qué ocurren las pérdidas de memoria. En el siguiente ejemplo, el objeto A se refiere al objeto B. La vida útil de A (t1 – t4) es mucho más larga que la de B (t2 – t3). Cuando B ya no se usa en la aplicación, A todavía tiene una referencia a él. De esta forma, Garbage Collector no puede eliminar B de la memoria. Esto posiblemente causaría un problema de falta de memoria, porque si A hace lo mismo con más objetos, entonces habría muchos objetos que no se recopilarían y consumirían espacio en la memoria.
También es posible que B contenga un montón de referencias de otros objetos. Los objetos a los que hace referencia B tampoco se recopilarán. Todos esos objetos no utilizados consumirán un valioso espacio de memoria.
3. ¿Cómo prevenir pérdidas de memoria?
Los siguientes son algunos consejos prácticos rápidos para prevenir pérdidas de memoria.
- Preste atención a las clases de Colección, como HashMap, ArrayList, etc., ya que son lugares comunes para encontrar fugas de memoria. Cuando se declaran
static
, su tiempo de vida es el mismo que el tiempo de vida de la aplicación. - Preste atención a los oyentes de eventos y las devoluciones de llamada. Puede producirse una pérdida de memoria si se registra un oyente pero no se anula el registro cuando la clase ya no se utiliza.
- «Si una clase administra su propia memoria, el programador debe estar alerta a las pérdidas de memoria».[1] A menudo, las variables miembro de un objeto que apuntan a otros objetos deben ser nulas.
4. Un pequeño cuestionario: ¿Por qué el método substring () en JDK 6 puede causar pérdidas de memoria?
Para responder a esta pregunta, es posible que desee leer Substring () en JDK 6 y 7.
Referencias:
[1] Bloch, Joshua. Java efectivo. Addison-Wesley Professional, 2008.
[2] Trabajo de desarrollador de IBM. http://www.ibm.com/developerworks/library/j-leaks/