Estaba hojeando 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 a objetos null
cuando ya no se necesiten.
En Java, ¿establecer referencias a objetos para null
mejorar el rendimiento o la eficiencia de la recolección de basura? Si es así, ¿en qué casos es un problema? ¿Clases de contenedores? 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?
Respuestas:
Depende un poco de cuándo estabas pensando en anular la referencia.
Si tiene una cadena de objetos A-> B-> C, una vez que A no sea accesible, A, B y C serán elegibles para la recolección de basura (asumiendo que nada más se refiere a B o C). No es necesario, y nunca ha sido necesario, establecer explícitamente las referencias A-> B o B-> C en nulo, 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. Por lo general, siempre debería pensar en eliminar objetos de listas, mapas, etc. llamando al método remove () apropiado.
El caso en el que solía haber algunos consejos para establecer referencias a nulo fue específicamente en un alcance largo en el que un objeto de memoria intensiva dejó de usarse en la mitad del alcance . Por ejemplo:
El razonamiento aquí fue que debido a que obj todavía está en el alcance, sin la anulación explícita de la referencia, no se puede recolectar como basura 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 determinar en qué punto ya no se usa una referencia de objeto local determinada.
fuente
No, no es un consejo obsoleto. Las referencias colgantes siguen siendo un problema, especialmente si, por ejemplo, está 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 se liberarán.Consulte Effective Java 2nd ed, Item 6: Elimine Obsolete Object References.
fuente
Campos de instancia, elementos de matriz
Si hay una referencia a un objeto, no se puede recolectar basura. Especialmente si ese objeto (y todo el gráfico detrás de él) es grande, solo hay una referencia que detiene la recolección de basura, y esa referencia ya no es realmente necesaria, esa es una situación desafortunada.
Los casos patológicos son el objeto que conserva una instancia no necesaria para todo el árbol DOM XML que se usó para configurarlo, el MBean que no se eliminó del registro o la referencia única a un objeto de una aplicación web no implementada que evita que se descargue un cargador de clases completo .
Entonces, a menos que esté seguro de que el objeto que contiene la referencia en sí será recolectado como basura de todos modos (o incluso entonces), debe anular todo lo que ya no necesita.
Variables de ámbito:
Si está considerando establecer una variable local en nula antes de que finalice su alcance, para que el recolector de basura pueda reclamarla y marcarla como "inutilizable a partir de ahora", debería considerar colocarla en un alcance más limitado. .
se convierte en
Los ámbitos largos y planos también son generalmente malos para la legibilidad del código. La introducción de métodos privados para dividir las cosas solo con ese propósito tampoco es inaudita.
fuente
En entornos con restricciones de memoria (por ejemplo, teléfonos móviles) esto puede resultar útil. Al establecer un valor nulo, el objeto no necesita esperar a que la variable salga del alcance para ser gc.
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.
fuente
En primer lugar, no significa nada para lo que esté configurando un objeto
null
. Te lo explico a continuación:En el segmento de código anterior, estamos creando el nombre
list1
de la variable de referencia delArrayList
objeto del objeto que se almacena en la memoria. Entonceslist1
se refiere a ese objeto y no es más que una variable. Y en la segunda línea de código estamos copiando la referencia delist1
alist2
. Entonces, volviendo a tu pregunta si lo hago:eso significa que
list1
ya no se refiere a ningún objeto que esté almacenado en la memoria, porlist2
lo que tampoco tendrá nada que hacer referencia. Entonces, si verifica el tamaño delist2
:Así que aquí llega el concepto de recolector de basura que dice «no tienes nada de qué preocuparte por liberar la memoria que tiene el objeto, lo haré cuando descubra que ya no se usará en programa y JVM me administrará».
Espero que quede claro el concepto.
fuente
Una de las razones para hacerlo es eliminar las referencias a objetos obsoletos. Puedes leer el texto aquí.
fuente