En qué situaciones en java es explícita anulación útil. ¿Ayuda de alguna manera al recolector de basura al hacer objetos inalcanzables o algo así? ¿Se considera una buena práctica?anulación explícita
Respuesta
En Java es puede ayudar si tiene un método muy antiguo, y la única referencia a un objeto es a través de una variable local. Al establecer esa variable local en nulo cuando ya no la necesita (pero cuando el método continuará ejecutándose durante un largo tiempo) puede ayudar al GC. (En C# esto rara vez es útil ya que el GC tiene en cuenta el "último uso posible". Esa optimización puede llegar a Java en algún momento, no sé).
Igualmente si tiene un campo de miembro refiriéndose a un objeto y ya no lo necesita, podría ayudar a GC ajustando el campo en nulo.
En mi experiencia, sin embargo, rara vez es en realidad útil para hacer cualquiera de estas cosas, y hace el código más desordenado. Muy pocos métodos realmente funcionan durante mucho tiempo, y establecer una variable en nulo en realidad no tiene nada que ver con lo que quiere que el método logre. No es una buena práctica hacerlo cuando no es necesario, y si usted necesita , debe ver si la refactorización podría mejorar su diseño en primer lugar. (Es posible que su método o tipo esté haciendo demasiado).
Tenga en cuenta que establecer la variable en nulo es completamente pasiva; no informa al recolector de basura que el objeto puede ser recolectado, simplemente evita que el recolector de basura ver esa referencia como una razón para mantener el objeto vivo la próxima vez que se ejecute (el GC).
En general, no es necesario (por supuesto, eso puede depender de la implementación de VM). Sin embargo, si usted tiene algo como esto:
private static final Map<String, String> foo;
y luego tener elementos en el mapa que ya no es necesario que no serán elegibles para la recolección de basura por lo que se necesita para eliminar de forma explícita. Hay muchos casos como este (los oyentes de eventos son otra área con la que esto puede suceder).
Pero hacer algo como esto:
void foo()
{
Object o;
// use o
o = null; // don't bother doing this, it isn't going to help
}
Editar (olvidó mencionar esto):
Si usted trabaja en él, usted debe encontrar que el 90-95% de las variables que se declaran puede ser hecho final. Una variable final no puede cambiar lo que apunta a (o cuál es su valor para las primitivas). En la mayoría de los casos en que una variable es definitiva, sería un error (error) que reciba un valor diferente mientras el método se está ejecutando.
Si desea poder establecer la variable a nulo después de su uso, no puede ser definitiva, lo que significa que tiene una mayor posibilidad de crear errores en el código.
Si anula un objeto que está a punto de salir de alcance de todos modos cuando se cierra el bloque de método, entonces no hay ningún beneficio en términos de recolección de basura. No es inusual encontrar personas que no entienden esto que trabajan muy duro para establecer un montón de cosas para anular innecesariamente.
Véase también WeakReference en J2SE.
De "Java efectivo": utilícelo para eliminar las referencias de objetos obsoletas.De lo contrario, puede provocar pérdidas de memoria que pueden ser muy difíciles de depurar.
public Object pop(){
if(size == 0)
throw new EmptyStatckException();
Object result = elements[--size];
elements[size] = null; //Eliminate Object reference
return result;
}
¿Seguro que quiere 'elements [size] == null' DESPUÉS de haber decrementado el tamaño? –
@AndrewLazarus me parece bastante correcto. Imagina una pila de tamaño 1. Almacena un solo elemento en 'elementos [0]'. El elemento se almacena en caché como resultado y la ubicación en la matriz anulada, lo que da como resultado un tamaño de pila de 0. – mtsz
Un caso especial lo encontré útil es cuando se tiene un objeto muy grande, y desea reemplazarlo con otro objeto grande. Por ejemplo, mira el siguiente código:
BigObject bigObject = new BigObject();
// ...
bigObject = new BigObject(); // line 3
Si una instancia de BigObject es tan grande que sólo puede tener uno de esos casos en el montón, la línea 3 fallará con OutOfMemoryError, debido a que la primera instancia no puede ser liberado hasta que se complete la instrucción de asignación en la línea 3, que obviamente es después de que la segunda instancia esté lista.
Ahora, si se establece en null bigObject justo antes de la línea 3:
bigObject = null;
bigObject = new BigObject(); // line 3
la primera instancia puede ser liberado cuando la JVM se queda sin pila durante la construcción de la segunda instancia.
anulación explícita puede ayudar con GC en algunas situaciones excepcionales en los que todos los siguientes son verdaderas:
- La variable es la única (no débil) referencia al objeto
- Puede garantía que ya no será necesario el objeto
- la variable estancia en alcance durante un período prolongado de tiempo (por ejemplo, es un campo de una instancia de objeto de larga vida)
- El compilador no es capaz de probar que el objeto ya no se usa, pero que son capaces de garantizar esto, sin embargo su análisis lógico superior del código :-)
En la práctica esto es bastante raro en buen código: si el objeto ya no es necesario, normalmente debería declararlo en un ámbito más estrecho de todos modos. Por ejemplo, si solo necesita el objeto durante una única invocación de un método, debe ser una variable local, no un campo en el objeto adjunto.
Una situación en la que la nulidad explícita es realmente útil: si null se utiliza para indicar un estado específico, a veces es necesario y útil establecerlo en un valor nulo. Nulo es un valor útil en sí mismo por un par de razones:
- cheques nulos son extremadamente rápidos código, de modo condicional que comprueba nula es típicamente más eficiente que muchas alternativas (por ejemplo Object.equals llamada())
- Obtienes una NullPointerException inmediata si tratas de desreferenciarla. Esto es útil porque es bueno Fail Fast estilo de codificación que le ayudará a detectar errores de lógica.
- 1. Anulación explícita de la función virtual
- 2. Conversión explícita de constructores en ActionScript3
- 3. Anulación Backbone.Collection.prototype.add
- 4. conversión explícita en Scala
- 5. Importación explícita de instancias
- 6. reducir, o recursión explícita?
- 7. aplicación explícita de IDisposable
- 8. var vs declaración explícita
- 9. anulación de encargo UITableViewCell
- 10. colocador Anulación de var
- 11. C++ Anulación ... sobrescritura?
- 12. Anulación de método
- 13. OnClick anulación evento
- 14. Encontrar métodos de anulación
- 15. Javascript: Anulación de XMLHttpRequest.open()
- 16. Sobrecarga, anulación y ocultación?
- 17. Anulación de Igualdad Operadores
- 18. JavaScript: Anulación de alerta()
- 19. QWidget keyPressEvent anulación
- 20. Desbordamiento de anulación: oculto
- 21. Métodos de anulación C++
- 22. Anulación machine.config por web.config
- 23. Anulación CSS text-transform
- 24. Anulación de GetHashCode
- 25. Anulación de métodos protegidos
- 26. Propósito de anulación
- 27. Anulación vs virtual
- 28. Instanciación explícita: ¿cuándo se usa?
- 29. Eliminación explícita de un shared_ptr
- 30. operador explícita de error bool
Buen punto sobre la parte 'final'. +1. Sin embargo, ¡conozco a algunos programadores que parecen considerar agregar como "clutering" su código! Vea esta respuesta: http://stackoverflow.com/questions/132777/do-you-prefix-your-instance-variable-with-this-in-java/135407#135407 – VonC
Hay muchos programadores que piensan esto. Es más o menos un argumento religioso. – Robin
Me gusta todo lo que hace que escribir errores en lugar de código sea más difícil :-) – TofuBeer