¿Están abiertos los campos estáticos para la recolección de basura?

95

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...
   }
}

¿myObject se recolectará como basura cuando ya no se use, o se quedará durante la vida útil del programa?

Michael Deardeuff
fuente

Respuestas:

112

Las variables estáticas no se pueden elegir para la recolección de basura mientras la clase está cargada. Se pueden recopilar cuando el cargador de clases respectivo (que fue responsable de cargar esta clase) se recopila para la basura.

Consulte la sección 12.7 de JLS Descarga de clases e interfaces

Una clase o interfaz puede ser descargada si y sólo si su cargador de clases definitorio puede ser reclamado por el recolector de basura [...] Las clases e interfaces cargadas por el cargador de arranque no se pueden descargar.

bruno conde
fuente
@bruno, según su enlace, ¿significa que un cargador de clases tiene una referencia a todas y cada una de las clases que carga, incluso si la clase cargada no tiene miembros estáticos?
Pacerier
@brunoconde, no creo que eso sea cierto en realidad. ¿Exactamente qué párrafo dice eso? (
Continúe
Cuándo el cargador de clases sería elegible para la recolección de basura. ?
Rohit Bandil
@RohitBandil: cuando es inalcanzable.
Stephen C
55

Las variables estáticas son referenciadas por objetos Class a los que hacen referencia ClassLoaders, por lo tanto, a menos que el ClassLoader descarte la clase de alguna manera (si eso es posible) o el ClassLoader mismo se vuelve elegible para la colección (más probablemente, piense en descargar aplicaciones web) las variables estáticas (o más bien, los objetos a los que hacen referencia) no se recopilarán.

Jon Skeet
fuente
1
¿ ClassSu cargador de clases hace referencia a los objetos que no contienen variables estáticas?
Pacerier
14

Si desea que un objeto temporal se utilice para la inicialización estática y luego se elimine, puede utilizar un bloque de inicialización estático, p. 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 basura después de que el bloque termine de ejecutarse.

finnw
fuente
13

myObject es una referencia y no un objeto . Un objeto se recolecta automáticamente como basura cuando ninguna referencia apunta a él porque es inalcanzable.

Así que también el objeto detrás de una referencia estática "myObject" puede ser recolectado como basura si lo desreferencia con

myObject = null;

y no hay otras referencias a este objeto.

Sin embargo, las referencias y variables estáticas permanecen durante la vida útil de su programa.

Felix Keil
fuente
¡Bienvenido a StackOverflow! Establecer el objeto al nullfinal del static blockes una opción viable. En mi caso, sin embargo, la vida útil del objeto debía ser más larga que la del bloque estático. El fin de la utilidad del objeto no fue muy concreto; por eso mi pregunta sobre la utilización del recolector de basura.
Michael Deardeuff
7

Creo que esto responde a su pregunta, básicamente no a menos que la clase provenga de un cargador de clases especial y eso descargue la clase.

Tom
fuente
0

La clave aquí es la recolección de basura de instancias de clase, es decir, objetos. La instancia de ClassLoader es, en esencia, un objeto. Entonces, si el objeto Classloader no se recolecta como basura, cualquier referencia de ellos almacenada en el montón (es decir, cosas estáticas) casi nunca será recolectada como basura. La excepción es el grupo de cadenas.

Entonces, antes de que de repente decida hacerlo, private static MyGiantClass myGiantObject = new MyGiantClass() piense dos veces, ya que he aprendido por las malas.

ha9u63ar
fuente