Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Java's ReferenceQueue

Do SoftReference and WeakReference really only help when created as instance variables? Is there any benefit to using them in method scope?

The other big part is ReferenceQueue. Besides being able to track which references are determined garbage, can Reference.enqueue() be used to forcibly register an object for garbage collection?

For example, would it be worth to create a method that takes some heavy memory resources (held by strong references) in an object and creating References to enqueue them?

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

(Imagine that Object in this case represents an object type that uses a lot of memory... like BufferedImage or something)

Does this have any realistic effect? Or is this just a waste of code?

like image 874
bgroenks Avatar asked Jan 22 '13 02:01

bgroenks


People also ask

What is the use of phantom reference in Java?

Phantom reference objects, which are enqueued after the collector determines that their referents may otherwise be reclaimed. Phantom references are most often used to schedule post-mortem cleanup actions.

What is weak reference in Java?

Weak reference objects, which do not prevent their referents from being made finalizable, finalized, and then reclaimed. Weak references are most often used to implement canonicalizing mappings. Suppose that the garbage collector determines at a certain point in time that an object is weakly reachable.


2 Answers

One common idiom with reference queues is to e.g. subclass WeakReference to attach information that's needed to clean up things, and then to poll a ReferenceQueue to get cleanup tasks.

ReferenceQueue<Foo> fooQueue = new ReferenceQueue<Foo>();  class ReferenceWithCleanup extends WeakReference<Foo> {   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(). } 

For example, the internals of Guava's CacheBuilder implementation when weakKeys are selected uses this approach.

like image 111
Louis Wasserman Avatar answered Oct 06 '22 00:10

Louis Wasserman


If an object has only WeakReferences (or no references whatsoever!) towards it, it can be garbage collected whenever Java needs to make more room in memory. So, you use WeakReferences whenever you want an object to remain in memory, but you don't need it to remain THAT badly (e.g. if Java needs to garbage collect it, no problem, you can get it back somehow and in the mean time Java has better performance)

Enqueuing a WeakReference allows you to iterate the ReferenceQueue and determine which references have been garbage collected and which have not. That's all - so only do it if you need to know this.

Read more: http://weblogs.java.net/blog/2006/05/04/understanding-weak-references

like image 37
Patashu Avatar answered Oct 06 '22 00:10

Patashu