java reference weak-references phantom-reference soft-references

Comprender las clases de referencia de Java: SoftReference, WeakReference y PhantomReference



weak-references phantom-reference (4)

¿Alguien puede explicar la diferencia entre las tres clases de referencia (o publicar un enlace a una buena explicación)? SoftReference > WeakReference > PhantomReference , pero ¿cuándo usaría 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 es incorrecto, pero qué debo hacer)? Perdón por las preguntas rápidas, pero estoy teniendo problemas para entender estas clases de Reference ... ¡Gracias!


La documentación de la biblioteca Java para el paquete java.lang.ref caracteriza la fortaleza decreciente de los tres tipos de referencia explícitos.

Utiliza una SoftReference cuando desea que el objeto al que se hace referencia 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 recolector necesite liberar memoria. En SoftReference , vincular una SoftReference significa, "Pin el objeto hasta que no puedas más".

Por el contrario, utilice una WeakReference cuando no desee influir en la duración del objeto al que se hace referencia; simplemente desea hacer una afirmación separada sobre el objeto al que se hace referencia, mientras siga vivo. La elegibilidad del objeto para la recopilación no está influenciada por la presencia de WeakReference vinculadas. Algo así como un mapeo externo desde la instancia del objeto a la propiedad relacionada, donde la propiedad solo necesita ser registrada siempre y cuando el objeto relacionado esté vivo, es un buen uso para WeakReference y WeakHashMap .

La última, PhantomReference es más difícil de caracterizar. Al igual que WeakReference , una PhantomReference enlazada no ejerce ninguna influencia sobre la duración del objeto al que se hace referencia. Pero a diferencia de los otros tipos de referencia, uno ni siquiera puede desreferenciar una referencia PhantomReference . En cierto sentido, no apunta a lo que apunta, por lo que los que llaman pueden decir. Simplemente permite asociar algunos datos relacionados con el objeto al que se hace referencia, datos que luego pueden ser inspeccionados y PhantomReference cuando PhantomReference se pone en cola en su ReferenceQueue relacionada. Normalmente, uno deriva un tipo de PhantomReference e incluye algunos datos adicionales en ese tipo derivado. Desafortunadamente, hay un poco de downcasting involucrado para hacer uso de dicho tipo derivado.

En su código de ejemplo, no es la ref referencia (o, si lo prefiere, "variable") que puede ser nula. Más bien, es el valor obtenido llamando a Reference#get() que puede ser nulo. Si se descubre que es nulo, ya es demasiado tarde; el objeto al que se hace referencia ya está en camino a ser recolectado:

final String val = ref.get(); if (null != val) { // "val" is now pinned strongly. } else { // "val" is already ready to be collected. }



Un enlace: https://community.oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references

PhantomHashMap no funcionaría muy bien, ya get siempre devuelve null para referencias fantasmas.

Los cachés son difíciles, por lo que SoftHashMap podría no funcionar tan bien como crees. Sin embargo, creo que la biblioteca de colecciones de Google contiene una implementación general del mapa de referencia.

Siempre debe verificar que get devoluciones no null . (Tenga en cuenta que no verifica que la Reference referencia en sí misma no sea null ). En el caso de cadenas internas, siempre lo hará, pero (como siempre) no trate de ser "inteligente" al respecto.


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á nulo. Y System.gc () es importante aquí.