java - tesis - ¿Están abiertos los campos estáticos para la recolección de basura?
tesis de residuos solidos municipales (6)
Dada una clase de utilidad hipotética que se usa solo en la configuración del programa:
class MyUtils {
private static MyObject myObject = new MyObject();
/*package*/static boolean doStuff(Params... params) {
// do stuff with myObject and params...
}
}
¿Será myObject recolectado como basura cuando ya no se usa, o se quedará por la vida del programa?
Creo que this responde a tu pregunta, básicamente no a menos que la clase provenga de un cargador de clases especial y que descargue la clase.
La clave aquí es la Colección de Basura de instancias de clase, es decir, Objetos. La instancia de ClassLoader es, en esencia, un Objeto. Por lo tanto, si el objeto Classloader no es basura, las referencias almacenadas en el montón (es decir, cosas estáticas) casi nunca serán recolectadas. La excepción es String pool.
Entonces, antes de que de repente decidas hacer private static MyGiantClass myGiantObject = new MyGiantClass()
Piensa dos veces como he aprendido de la manera difícil.
Las variables estáticas no se pueden elegir para la recolección de basura mientras se carga la clase. Se pueden recopilar cuando el cargador de clases respectivo (que se encargó de cargar esta clase) se recoge para la basura.
Consulte la Sección 12.7 de JLS Descarga de clases e interfaces
Una clase o interfaz puede descargarse si y solo si el cargador de basura puede reclamar su cargador de clases definidor [...] Las clases e interfaces cargadas por el cargador bootstrap no se pueden descargar.
Las variables estáticas son referenciadas por objetos Class a los que hace referencia ClassLoaders, a menos que el ClassLoader elimine la clase de alguna manera (si eso es posible) o el ClassLoader se vuelve elegible para la recolección (más probable - piense en descargar webapps) las variables estáticas (o más bien, los objetos a los que hacen referencia) no serán recolectados.
Si desea utilizar un objeto temporal para la inicialización estática y luego desecharlo, puede usar un bloque de inicializador estático, por ej.
class MyUtils {
static
{
MyObject myObject = new MyObject();
doStuff(myObject, params);
}
static boolean doStuff(MyObject myObject, Params... params) {
// do stuff with myObject and params...
}
}
dado que el bloque de inicializador estático es un tipo especial de método estático, myObject es una variable local y se puede recolectar como basura después de que el bloque termina de ejecutarse.
myObject es una referencia y no un objeto . Un objeto es recolectado automáticamente como basura cuando ninguna referencia lo señala porque es inalcanzable.
Así que también el objeto detrás de una referencia estática "myObject" puede ser recolectado como basura si lo desreferenciamos con
myObject = null;
y no hay otras referencias a este objeto.
Sin embargo, las referencias estáticas y las variables permanecen durante la vigencia de su programa.