
En Java un objeto siempre ha de estar referenciado por una variable; en el momento que un objeto deja de estar referenciado se activa la rutina de recolección de memoria; se puede decir que el objeto es liberado y la memoria que ocupa puede ser reutilizada.
Ejemplo
Punto punto = new Punto(1,2);
La sentencia punto = null provoca que el objeto Punto sea liberado automáticamente.
El propio sistema se encarga de recolectar los objetos en desuso para aprovechar la memoria ocupada. Para ello hay un proceso que se activa periódicamente y toma los objetos que no están referenciados por ninguna variable. El proceso lo realiza el método System.gc (garbage collection). Por ejemplo, el siguiente método crea objetos Contador y después se liberan al perder su referencia.
void objetos() {
Contador k, g, r, s;
// se crean cuatro objetos
k = new Contador();
g = new Contador();
r = new Contador();
s = new Contador();
/* la siguiente asignación hace que g referencie al mismo objeto que k,
además el objeto original de g será automáticamente recolectado */
g = k;
/* ahora no se activa el recolector porque g sigue apuntando al objeto */
k = null;
/* a continuación si se activa el recolector para el objeto original de r */
r = new Contador();
} // se liberan los objetos actuales apuntados por g, r, s
Método finalize()
El método finalize() es especial, se llama automáticamente si ha sido definido en la clase, justo antes que la memoria del objeto «recolectado» vaya a ser devuelta al sistema. El método no es un destructor del objeto, no libera memoria; en algunas aplicaciones se puede utilizar para liberar ciertos recursos del sistema.
Regla
finalize() es un método especial con estas características:
- No devuelve valor, es de tipo void.
- No tiene argumentos.
- No puede sobrecargarse.
- Su definición es opcional.
Ejemplo
Se declaran dos clases, cada una con su método finalize(). El método main() crea objetos de ambas clases; las variables que referencian a los objetos se modifican para que cuando se active la recolección automática de objetos se libere la memoria de estos; hay una llamada a System.gc() para no esperar a la llamada interna del sistema.
import java.io.*;
public class Demo {
private int datos;
public Demo() {
datos = 0;
}
protected void finalize() {
System.out.println(«Fin de objeto Demo»);
}
}
import java.io.*;
public class Prueba {
private double x;
public Prueba() {
x = -1.0;
}
protected void finalize() {
System.out.println(«Fin de objeto Prueba»);
}
}
public class ProbarDemo {
public static void main(String[] args) {
Demo d1, d2;
Prueba p1, p2;
d1 = new Demo();
p1 = new Prueba();
System.gc(); // no se libera ningún objeto
p2 = p1;
p1 = new Prueba();
System.gc(); // no se libera ningún objeto
p1 = null;
d1 = new Demo();
System.gc(); // se liberan dos objetos
d2 = new Demo();
} // se liberan los objetos restantes
}