Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test a weak reference before using it java

Tags:

In a multithreaded Android project, I'm seeing code like this:

final WeakReference<MyClass> myClassObjectWeakRef =                 new WeakReference<MyClass>(aMyClassObject); 

...then somewhere else:

if (myClassObjectWeakRef.get() != null) {   myClassObjectWeakRef.get().someMethod(); } 

I'm pretty sure there is a possible race condition between the check and the use of the reference, if the last strong reference to the object is released between the two in another thread, but I can't find any documentation or anyone which/who can confirm this better than with a "you're probably right".

I would think the only right way to test & use a weak reference is done like this:

MyClass myObject = myClassObjectWeakRef.get(); // we now have a strong reference, or null: standard checks apply. if (myObject != null) {   myObject.someMethod(); } 

I'm very confident that the second method is 100% safe, but I wonder if there is some Java/compiler sugar/magic that I don't know about, which would make the first method safe.

So, is the first method 100% safe, or not?

like image 253
Georges Avatar asked Dec 23 '14 21:12

Georges


People also ask

What is weak reference in Java and how it is used?

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.

How do you create a weak reference in Java?

To create a Weak Reference Object, we must explicitly specify this to the JVM. Why Weak Reference Objects are used: Unlike C/C++, Java supports Dynamic Garbage Collection. This is performed when the JVM runs the Garbage Collector.

What's the difference between Softreference and Weakreference in Java?

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.

How are weak references implemented?

So, weakref is itself an object, when you put weak reference to an object in some container, you actually put reference to weakref object. Each ref-countable object has field to store pointer to its weakref, which is NULL until weakref to that object is actually requested.


1 Answers

The first method is definitely unsafe. Each call to get is independent. There is nothing preventing the GC from clearing the weakly reachable object after the first get and before the second.

The javadoc states

Suppose that the garbage collector determines at a certain point in time that an object is weakly reachable. At that time it will atomically clear all weak references to that object and all weak references to any other weakly-reachable objects from which that object is reachable through a chain of strong and soft references.

That can be at any point in time. Calling get(), which (potentially) pushes a reference to the object on the stack temporarily makes the object strongly reachable (it's on a thread's stack), but that reach-ability disappears the moment the comparison with null finishes. After that moment, the GC can determine that the object is weakly reachable and clear its reference. You'd then get a NullPointerException.

Use your second method. But note that by assigning it to a variable, you are making the referenced object strongly reachable.

like image 151
Sotirios Delimanolis Avatar answered Sep 29 '22 11:09

Sotirios Delimanolis