Suppose ref is a WeakReference object pointing to (or at a certain moment having pointed to) an object obj. If a call ref.get() happens-before (or at least precedes in the program order?) an execution of Reference.reachabilityFence(obj), is there any chance that the returnee of the ref.get() may be null? (in addition, I want to ask this question again after replacing the part about the observation of null through ref.get() by the acquisition of the ref through queue polling.)
I ask this question because I am not quite sure how Reference#reachabilityFence works in terms of Java Memory Model, especially when it interacts with WeakReferences (and other similar references). The following list is all the places where specifications related to this topic exist, as far as I know:
- (a)JSL 17.4.MemoryModel
- (b)JSL 12.6.Finalization of Class Instances, especially (b2)12.6.2. Interaction with the Memory Model
- (c)WeakReference.
- (d)Reference#reachabilityFence
The problem is that the terminology used in (c) and (d) is vague and unclear compared to the one used in (a) and (b).
If the answer to the question written at the beginning is sadly yes, how can I make all the ref.get() calls happening-before a certain point of code? If not, how can we prove that based on the specifications written in (a)(b)(c)(d) or anywhere else?
Although the answer to the first question may be enough for my use, I also want the specifications in (c) and in (d) to become clear, so let me ask more questions below.
First, (c)WeakReference says that at a certain point of time the gc determines objects to be weakly-reachable, at the same time clears weak refs, and at the same time declares those objects as finalizable. According to (b2), reachability checks and finalizability declarations take place at reachability decision points. So the "certain point of time" must be one of the reachability decision points, right ? If so, other questions come up. (b2) also says reachability desicion points are NOT actual points (unlike writes and reads) in the code or on the program order; they are virtual points that are only related to actions through come-before / come-after relations, which are independent of program ordering. So... weak refs are cleared at the decision point, which is not anywhere on the code. What does it exactly mean ? On what condition can WeakReference#get() be null? cannot be null? Is it the come-before / come-after relation between the decision point and the WeakReference#get() that we need? Or the come-before / after relation between the decision point and some other action which has a certain memory-model-related relation to the WeakReference#get()?
Next, (d)reachabilityFence. It says a call of this method keeps the object's strong reachability and thus makes it unreclaimable until after the call. Can I interpret it as saying that the call keeps the object's strong reachability until after the call ? Technically it is not saying so. But if there is no specification about until when the strong reachability are kept, the part about keeping the strong reachability is useless. (And the other half talking about the undefined concept "unreclaimability" is useless from the beginning.) So the strong reachability is maintained until after the call -- but what does the word 'after' exactly mean ? Program order? Happens before? The order in which comissions take place? Besides, I think objects become unreachable at a certain decision point as described in (b2). What determines whether a certain call of reachabilityFence affects a certain decision point or it does not? The come-before / come-after relation between the fence and the decision point? Obviously not, because since the call of fence is neither a write nor a read nor a synchronization action, it makes no difference whether a certain fence call comes-before or comes-after a certain decision point.
I suspect (c) and (d) are too vague and thus it is impossible to answer basic questions like my first one.