¿Alguien puede explicar la diferencia entre las tres clases de referencia (o publicar un enlace a una buena explicación)? SoftReference
> WeakReference
> PhantomReference
, Pero cuando iba a utilizar cada uno? ¿Por qué hay un WeakHashMap
pero no SoftHashMap
o PhantomHashMap
?
Y si uso el siguiente código ...
WeakReference<String> ref = new WeakReference<String>("Hello!");
if (ref != null) { // ref can get collected at any time...
System.gc(); // Let's assume ref gets collected here.
System.out.println(ref.get()); // Now what?!
}
...¿lo que pasa? ¿Tengo que verificar si ref
es nulo antes de cada declaración (esto está mal, pero qué debo hacer)? Perdón por las preguntas rápidas, pero tengo problemas para entender estas Reference
clases ... ¡Gracias!
java
reference
weak-references
phantom-reference
soft-references
Haywood Jablomey
fuente
fuente
WeakHashMap
pero noSoftHashMap
oPhantomHashMap
Excelente, por qué no me di cuenta de esto antes ... ??ref != null
cheque no tiene sentido.ref
nunca lo seránull
.strongRef --> weakRef --> objA
. Ahora, seráobjA
GCed o no, ya que tiene una referencia indirecta destrongRef
.Respuestas:
La documentación de la
java.lang.ref
biblioteca de Java para el paquete caracteriza la fuerza decreciente de los tres tipos de referencia explícitos.Utiliza un
SoftReference
cuando desea que el objeto referenciado permanezca activo hasta que el proceso del host se esté quedando sin memoria. El objeto no será elegible para la recopilación hasta que el recopilador necesite liberar memoria. Enunciado libremente, vincular unSoftReference
medio, "Fija el objeto hasta que no puedas más".Por el contrario, utilice a
WeakReference
cuando no desee influir en la vida útil del objeto al que se hace referencia; simplemente desea hacer una afirmación separada sobre el objeto al que se hace referencia, siempre que permanezca vivo. La elegibilidad del objeto para la colección no está influenciada por la presencia de enlacesWeakReference
. Algo así como un mapeo externo de la instancia del objeto a la propiedad relacionada, donde la propiedad solo necesita registrarse mientras el objeto relacionado esté vivo, es un buen uso paraWeakReference
s yWeakHashMap
.El último ...
PhantomReference
es más difícil de caracterizar. PorWeakReference
ejemplo, tal límitePhantomReference
no ejerce ninguna influencia en la vida útil del objeto referenciado. Pero a diferencia de los otros tipos de referencia, ni siquiera se puede eliminar la referencia aPhantomReference
. En cierto sentido, no apunta a lo que apunta, por lo que las personas que llaman pueden saber. Simplemente le permite a uno asociar algunos datos relacionados con el objeto referenciado, datos que luego se pueden inspeccionar y actuar sobre ellos cuandoPhantomReference
se pone en cola en su relacionadoReferenceQueue
. Normalmente, se deriva un tipoPhantomReference
e incluye algunos datos adicionales en ese tipo derivado. Desafortunadamente, hay algo de abatimiento involucrado para hacer uso de un tipo derivado.En su código de ejemplo, no es la
ref
referencia (o, si lo prefiere, la "variable") la que puede ser nula. Más bien, es el valor obtenido al llamarReference#get()
que puede ser nulo. Si se determina que es nulo, es demasiado tarde; el objeto referenciado ya está en camino de ser recopilado:final String val = ref.get(); if (null != val) { // "val" is now pinned strongly. } else { // "val" is already ready to be collected. }
fuente
strongRef --> weakRef --> objA
. Ahora, seráobjA
GCed o no, ya que tiene una referencia indirecta destrongRef
.objA
es elegible para la recolección como basura. Fijar unWeakReference
no ejerce ninguna influencia sobre el objeto al queWeakReference
apunta.objA
que se recolecte basura, la referencia débil debe eliminarse primero a la derecha. Y una fuerte referencia está apuntando a los débiles referencia por el que los débiles no elegible para ser ref GCedWeakReference
no es necesario recolectarlo para permitirobjA
su recolección. ElWeakReference
no se mantieneobjA
vivo. Más bien, es una forma de encontrarobjA
mientras está vivo, sin influir en esa vida, y detectar cuándo el coleccionista ya se lo llevó.Un enlace: https://community.oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references
PhantomHashMap
No funcionaría muy bien, ya queget
siempre devuelvenull
para referencias fantasmas.Los cachés son difíciles, por lo
SoftHashMap
que es posible que no funcionen tan bien como crees. Sin embargo, creo que la biblioteca de colecciones de Google contiene una implementación de mapa de referencia general.Siempre debe verificar que
get
devuelve no-null
. (Tenga en cuenta que no comprobar que laReference
referencia en sí no sea-null
.) En el caso de cadenas internas, siempre lo hará, pero (como siempre) no intente ser "inteligente" al respecto.fuente
strongRef --> weakRef --> objA
. Ahora, seráobjA
GCed o no, ya que tiene una referencia indirecta destrongRef
.También debe mencionarse, como se indica en el comentario de Truong Xuan Tinh, aquí: http://blog.yohanliyanage.com/2010/10/ktjs-3-soft-weak-phantom-references/
Que JRockit JVM implementa referencias débiles / suaves / fantasmas de manera diferente a Sun JVM.
fuente
String str = new String("hello, world"); WeakReference<String> ref = new WeakReference<String>(str); str = null; if (ref != null) { System.gc(); System.out.println(ref.get()); }
En este caso, generará un valor nulo. La llamada a
System.gc()
es importante aquí.fuente