Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ReferenceQueue and WeakReference

Tags:

java

I want to properly close Closeable object when it's no longer referenced by other threads.

I wrote some small test, but after object is enqueued the get method return null, i.e. the poll method returns proper Object which has no referent.

  public static void main(String[] args)
  {
   ReferenceQueue<Closeable> reaped = new ReferenceQueue<Closeable>();
   Closeable s = <SOME CLOSEABLE IMPL>;
   WeakReference<Closeable> ws = new WeakReference<Closeable>(s, reaped);
   s = null;

   System.gc();
   Closeable ro = (Closeable)reaped.poll().get();
   ro.close();
  }

Thanks in advance. Any help will be appreciated.

like image 234
yan Avatar asked Jun 04 '12 07:06

yan


People also ask

What's the difference between Softreference and WeakReference?

A Soft reference is eligible for collection by garbage collector, but probably won't be collected until its memory is needed. i.e. garbage collects before OutOfMemoryError . A Weak reference is a reference that does not protect a referenced object from collection by GC.

What is the use of WeakReference?

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.

What is a weak reference and how could it be useful to us?

A weak reference allows the garbage collector to collect an object while still allowing an application to access the object. If you need the object, you can still obtain a strong reference to it and prevent it from being collected.

What is ReferenceQueue in Java?

A ReferenceQueue is a simple data structure onto which the garbage collector places reference objects when the reference field is cleared (set to null).


1 Answers

First, if it is only about closing, use PhantomReference. Next, from the reference queue, poll() does not guarantee that you will get the reference back. and you will never get the actual object (referent) back.

If you want to make sure your Closeables are closed you have to keep track of them yourself lets say in a Map<Reference<?>, Closeable>. Then when you poll() your reference queue, you will eventually get the ref then you have to use it to get the Closeable from the map.

   class MyThing {
      Closeable c;
   }

   Map<Reference<MyThing>, Closeable> m = new HashMap();
   ReferenceQueue<MyThing> reaped = new ReferenceQueue<MyThing>();

   MyThing mt = new MyThing();
   mt.c = new MyClosable();

   Reference<MyThing> pref = new PhantomReference<MyThing>(mt, reaped);
   m.put(pref, mt.c);

   mt = null;


   System.gc();
   Reference<MyThing> rf = reaped.poll();
   while (rf != null) {
     m.get(rf).close(); 
     rf = reaped.poll();
   }

Note If you don't have a real reason to do this or if you do not understand what are you really doing, DO NOT do this kind of thing.

You can close your files in finally and BTW if it is about files, sockets, etc, they are closed for you (they already implement finalize()

like image 199
Op De Cirkel Avatar answered Sep 26 '22 03:09

Op De Cirkel