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.
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.
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.
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.
A ReferenceQueue is a simple data structure onto which the garbage collector places reference objects when the reference field is cleared (set to null).
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 Closeable
s 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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With