Usando la ReferenceQueue de Java

¿ SoftReference y WeakReference realmente solo ayudan cuando se crean como variables de instancia? ¿Hay algún beneficio al usarlos en el scope del método?

La otra gran parte es ReferenceQueue . Además de poder rastrear qué referencias son basura determinada, ¿se puede usar Reference.enqueue() para registrar forzosamente un objeto para la recolección de basura?

Por ejemplo, ¿valdría la pena crear un método que tome algunos recursos pesados ​​de memoria (retenidos por referencias fuertes) en un objeto y crear Referencias para ponerlos en cola?

 Object bigObject; public void dispose() { ReferenceQueue queue = new ReferenceQueue(); WeakReference ref = new WeakReference(bigObject, queue); bigObject = null; ref.enqueue(); } 

(Imagine que Object en este caso representa un tipo de objeto que utiliza mucha memoria … como BufferedImage o algo así)

¿Tiene esto algún efecto realista? ¿O es esto solo una pérdida de código?

Una expresión común con colas de referencia es, por ejemplo, subclase WeakReference para adjuntar información que se necesita para limpiar cosas, y luego sondear una ReferenceQueue para obtener tareas de limpieza.

 ReferenceQueue fooQueue = new ReferenceQueue(); class ReferenceWithCleanup extends WeakReference { Bar bar; ReferenceWithCleanup(Foo foo, Bar bar) { super(foo, fooQueue); this.bar = bar; } public void cleanUp() { bar.cleanUp(); } } public Thread cleanupThread = new Thread() { public void run() { while(true) { ReferenceWithCleanup ref = (ReferenceWithCleanup)fooQueue.remove(); ref.cleanUp(); } } } public void doStuff() { cleanupThread.start(); Foo foo = new Foo(); Bar bar = new Bar(); ReferenceWithCleanup ref = new ReferenceWithCleanup(foo, bar); ... // From now on, once you release all non-weak references to foo, // then at some indeterminate point in the future, bar.cleanUp() will // be run. You can force it by calling ref.enqueue(). } 

Por ejemplo, las aplicaciones internas de la implementación de CacheBuilder de Guava cuando se seleccionan weakKeys utilizan este enfoque.

Si un objeto solo tiene WeakReference (¡o ninguna referencia!) Hacia él, se puede recolectar basura cada vez que Java necesite hacer más espacio en la memoria. Por lo tanto, utiliza WeakReference s siempre que quiera que un objeto permanezca en la memoria, pero no necesita que permanezca así de mal (por ejemplo, si Java necesita recoger basura, no hay problema, puede recuperarlo de alguna manera y en el medio tiempo Java tiene un mejor rendimiento)

La colocación de una WeakReference permite iterar la ReferenceQueue y determinar qué referencias han sido recolectadas y cuáles no. Eso es todo, solo hazlo si necesitas saber esto.

Leer más: http://weblogs.java.net/blog/2006/05/04/understanding-weak-references

Una cosa común que hacer es crear mapas de referencias suaves.

 Map> cache = new HashMap<>(); Set thingsIAmCurrentlyGetting = new HashSet(); Object mutex = new Object(); BigThing getThing(String key) { synchronized(mutex) { while(thingsIAmCurrentlyGetting.contains(key)) { mutex.wait(); } SoftReference ref = cache.get(key); BigThing bigThing = ref == null ? null : ref.get(); if(bigThing != null) return bigThing; thingsIAmCurrentlyGetting.add(key); } BigThing bigThing = getBigThing(key); // this may take a while to run. synchronized(mutex) { cache.put(key, bigThing); thingsIAmCurrentlyGetting.remove(key); mutex.notifyAll(); } return bigThing; } 

Estoy mostrando mi vieja escuela aquí – los nuevos paquetes de Java probablemente tienen formas mucho mejores de hacer esto.

No estoy seguro de cuál es la pregunta aquí, pero:

1) suave ref intente mantener la referencia hasta que jvm realmente realmente necesite la memoria. Ideal para caches, especialmente para LRU. Mire muchos ejemplos en Guava.

2) ref débil no intente evitar que gc libere el objeto en absoluto. Se usan si quieres saber si ese objeto todavía se usa en alguna parte. Por ejemplo, se usan para almacenar información sobre hilos y clases, de modo que cuando el hilo o la clase ya no se utiliza, podemos descartar la metainformación relacionada con eso.

3) la referencia fantasma son débiles pero sin dejar que hagas referencia al objeto real. De esta manera, puede estar seguro de que al pasar el fantasma no puede reanudar el objeto real (este es un riesgo con ref débil). También la referencia fantasma está bloqueando el objeto que se recogerá hasta que borre la referencia.

ReferenceQueue: no enque cosas allí. gc lo hará por ti. Le permiten saber cuándo se publican algunas referencias, sin tener que verificarlas una a una.