una tutorial obtener objetos objeto metodos manejo instanciar genericos genericas datos crear con como clases clase atributos java garbage-collection performance

tutorial - objetos en java



¿El establecimiento de objetos Java a null hace algo más? (6)

Estaba navegando por algunos libros antiguos y encontré una copia de "Practical Java" de Peter Hagger. En la sección de rendimiento, hay una recomendación para establecer referencias de objeto a null cuando ya no sea necesario.

En Java, ¿el ajuste de las referencias de objetos a null mejora el rendimiento o la eficiencia de la recolección de basura? Si es así, ¿en qué casos es esto un problema? Clases de contenedor? ¿Composición de objetos? ¿Clases internas anónimas?

Veo esto en el código con bastante frecuencia. ¿Es este consejo de programación obsoleto o sigue siendo útil?


Depende un poco cuando estabas pensando en anular la referencia.

Si tiene una cadena de objetos A-> B-> C, entonces una vez que A no es alcanzable, A, B y C serán elegibles para la recolección de basura (suponiendo que nada más se refiera a B o C). No es necesario, y nunca ha sido necesario, establecer explícitamente referencias A-> B o B-> C a nulas, por ejemplo.

Aparte de eso, la mayoría de las veces el problema no surge realmente, porque en realidad se trata de objetos en colecciones. En general, siempre debe pensar en eliminar objetos de las listas, mapas, etc. llamando al método apropiado remove ().

El caso en el que solía haber algún consejo para establecer referencias a nulo fue específicamente en un largo alcance donde un objeto con uso intensivo de memoria dejó de utilizarse a mitad del alcance . Por ejemplo:

{ BigObject obj = ... doSomethingWith(obj); obj = null; <-- explicitly set to null doSomethingElse(); }

El razonamiento aquí fue que, dado que obj todavía está dentro del alcance, entonces, sin la anulación explícita de la referencia, no se convierte en basura coleccionable hasta que se complete el método doSomethingElse () . Y este es el consejo que probablemente ya no se aplica a las JVM modernas : resulta que el compilador JIT puede calcular en qué punto ya no se utiliza una referencia de objeto local dada.


En entornos de memoria restrictiva (por ejemplo, teléfonos celulares) esto puede ser útil. Al establecer nulo, el objeto no necesita esperar la variable para salir del alcance que se va a generar.

Para la programación diaria, sin embargo, esta no debería ser la regla, excepto en casos especiales como el que citó Chris Jester-Young.


En primer lugar, no significa nada de lo que está estableciendo un objeto nulo. Lo explico a continuación:

List list1=new ArrayList(); List list2=list1;

En el segmento de código anterior, lo que estamos haciendo, en realidad estamos creando el nombre de la variable de referencia del objeto list1 del Objeto ArrayList que está almacenado en la memoria. Entonces list1 está refiriendo ese objeto y notando más que una variable. Y en la segunda línea de código estamos copiando la referencia de list1 en list2. Entonces, volviendo a tu pregunta si lo hago:

list1=null;

eso significa que list1 ya no está refiriendo ningún objeto que está almacenado en la memoria, por lo que list2 tampoco tendrá nada a que referirse. Entonces, si comprueba el tamaño de list2:

list2.size(); //it gives you 0

Así que aquí llega el concepto de recolector de basura que dice "no hay nada de qué preocuparse por liberar la memoria que guarda el objeto, lo haré cuando descubra que ya no se usará en el programa y JVM me administrará".

Espero que aclare el concepto.


No, no es un consejo obsoleto. Las referencias colgantes siguen siendo un problema, especialmente si usted está, por ejemplo, implementando un contenedor de matriz expandible ( ArrayList o similar) utilizando una matriz preasignada. Los elementos más allá del tamaño "lógico" de la lista deben anularse, o de lo contrario no serán liberados.

Ver Effective Java 2nd ed, Item 6: Eliminar Referencias a Objetos Obsoletos.


Una de las razones para hacerlo es eliminar referencias de objetos obsoletas. Puedes leer el texto here.


Campos de instancia, elementos de la matriz

Si hay una referencia a un objeto, no puede ser basura recolectada. Especialmente si ese objeto (y todo el gráfico detrás de él) es grande, solo hay una referencia que está deteniendo la recolección de basura, y esa referencia ya no es necesaria, esa es una situación desafortunada.

Los casos patológicos son el objeto que conserva una instancia no intencional para todo el árbol XML DOM que se usó para configurarlo, el MBean que no se registró, o la única referencia a un objeto de una aplicación web no desplegada que impide que un cargador de clases completo se descargue .

Por lo tanto, a menos que esté seguro de que el objeto que contiene la referencia en sí será basura recogida de todos modos (o incluso entonces), debe anular todo lo que ya no necesita.

Variables de alcance:

Si está considerando establecer una variable local en nulo antes del final de su alcance, para que pueda ser recuperado por el recolector de basura y marcarlo como "inutilizable a partir de ahora", debería considerar ponerlo en un ámbito más limitado en su lugar .

{ BigObject obj = ... doSomethingWith(obj); obj = null; // <-- explicitly set to null doSomethingElse(); }

se convierte

{ { BigObject obj = ... doSomethingWith(obj); } // <-- obj goes out of scope doSomethingElse(); }

Los alcances largos y planos generalmente son malos para la legibilidad del código. Tampoco es extraño que se introduzcan métodos privados para romper las cosas solo para ese propósito.