2009-03-13 13 views

Respuesta

76

Los métodos estáticos son solo métodos, no se almacenan en el montón, simplemente no usan el parámetro "this".

Las variables estáticas sirven como "raíces" para el GC. Como resultado, a menos que los establezca explícitamente como nulos, vivirán mientras viva el programa, y ​​así todo se puede acceder desde ellos.

Una situación solo se considera una pérdida de memoria si desea que la memoria se vuelva gratuita y no se vuelva gratuita. Si pretendes que tu variable estática contenga una referencia a un objeto durante parte del tiempo, y te olvidas de establecerlo como nulo cuando hayas terminado con ese objeto, es probable que termines con una fuga. Sin embargo, si lo coloca en la variable estática y tiene la intención de que permanezca allí mientras se ejecuta el programa, entonces definitivamente no es una fuga, es más probable que sea un "singleton permanente". Si el objeto se recuperó mientras usted quería que aún existiera, eso hubiera sido muy malo.

En cuanto a su pregunta sobre el montón: Todos los objetos en Java existen ya sea en el montón o en la pila. Los objetos se crean en el montón con el nuevo operador. A continuación, se les adjunta una referencia. Si la referencia se vuelve nula o cae fuera del alcance (por ejemplo, al final del bloque), el GC se da cuenta de que no hay forma de volver a alcanzar ese objeto nunca más y lo reclama. Si su referencia está en una variable estática, nunca se saldrá del alcance, pero puede establecerla en nulo o en otro objeto.

+0

IIRC los campos estáticos serán GCed tan pronto como la clase que los declara es GCed.Si la instancia elast de la clase ha desaparecido, la declaración de clase irá y los campos estáticos con ella. – ordnungswidrig

+1

No estoy seguro de si @ o11rig es completamente exacto, pero creo que el GC puede recopilar estadísticas para las clases que no tienen miembros bajo ciertas circunstancias. He escuchado esto de un par de fuentes, pero nunca escuché una explicación exacta. –

+0

Ligera objeción: todos los objetos Java * viven en el montón. Las referencias * y las primitivas de Object * se pueden almacenar en la pila si son locales del método que se está ejecutando actualmente, y se almacenan en el montón de otro modo. (Excepto en cualquier JVM moderna con un JIT, donde el optimizador de JIT puede colocar objetos donde quiera, siempre y cuando * actúe * como si los objetos estuvieran en el montón). Y podría argumentarse que los métodos estáticos - o , al menos, el bytecode de Java que los implementa, también vive en el montón, como parte del objeto Class que representa la clase en la que se definieron. –

1

Siempre que pueda hacer referencia a estas variables desde algún lugar del código, no puede hacerlo mediante GCed, lo que significa que estarán allí hasta el final de la aplicación.

Puede llamarlo una pérdida de memoria, no lo llamaría una pérdida de memoria, por lo general, una pérdida de memoria es la memoria que normalmente espera recuperar pero nunca lo hace, o solo recupera una parte. Además, las pérdidas de memoria suelen empeorar con el tiempo (por ejemplo, cada vez que llamas a un método, se "filtra" más memoria), sin embargo, en este caso, el uso de la memoria para esas variables es (algo) estático.

+0

No es necesario hacer referencia a variables estáticas desde su código ... el cargador de clases mantiene permanentemente una referencia y, por lo tanto, el GC nunca entrará en acción. – ReneS

1

No causará una pérdida de memoria en el sentido clásico de C ... Por ejemplo

Class A{ 

static B foo; 

... 

static void makeFoo(){ 
    foo = new B(); 
    foo = new B(); 
} 

En este caso, una llamada a makeFoo() no se traducirá en una pérdida de memoria, como el primera instancia puede ser basura recolectada.

2

Los objetos a los que hace referencia directa o indirectamente la estática permanecerán en el montón hasta que se pueda recopilar el cargador de clases adecuado. Hay casos (ThreadLocal, por ejemplo) donde otros objetos hacen referencia indirectamente al cargador de clases, lo que hace que permanezca sin recoger.

Si tiene una lista estática, por ejemplo, y agrega referencias dinámicamente a ella, puede terminar fácilmente con "problemas de contención de por vida del objeto". Evita la estática mutable por muchas razones.

3

Si tiene un hashmap estático y agrega datos ... los datos nunca desaparecerán y tendrá una fuga en caso de que ya no los necesite. Si necesita los datos, no se trata de una fuga, sino de una enorme pila de memoria.

+0

Suponga que hashmap estático tiene muchos objetos; e hice la referencia del mapa a nulo (no a todos los objetos que contiene)? ¿Es una pérdida de memoria? ya que ha declarado que "el cargador de clases tiene permanentemente una referencia estática y, por lo tanto, el GC nunca funcionará". –

+0

Si configura la referencia estática como nula y no ha hecho referencia a ese mapa en ningún otro lugar, la memoria se liberará. Los objetos referenciados en ese mapa también se liberarán si no son referenciados por otra persona. – ReneS

Cuestiones relacionadas