Reachability of an object when a thread is running one of its methods
Carlo de Wolf
cdewolf at redhat.com
Thu Dec 6 00:51:38 PST 2012
On 12/05/2012 01:44 PM, Andrew Haley wrote:
> On 12/05/2012 12:02 PM, Carlo de Wolf wrote:
>> On 12/05/2012 10:59 AM, Andrew Haley wrote:
>>> On 12/05/2012 09:00 AM, Carlo de Wolf wrote:
>>>
>>>> The example further on shows that an object reference which is on the
>>>> heap can be optimized away and thus the object can be finalized too
>>>> early. A reference coming off the stack is allowed to be nullified and
>>>> it would not trigger finalization. Hence a reference on the stack is a
>>>> strong one.
>>> Carlo, you are making this very hard work. You write things like
>>>
>>> "A reference coming off the stack is allowed to be nullified and
>>> it would not trigger finalization." but without reference to the
>>> specification. Does it say anything in the specification to
>>> support this claim?
>> JLS 7 12.6.1
>>
>> "If these optimizations are allowed for references that are stored
>> on the heap, then a Java compiler can detect that the
>> finalizerGuardian field is never read, null it out, collect the
>> object immediately, and call the finalizer early."
>>
>> In effect, the optimization is allowed for a reference stored on the
>> stack, without having the side effect of an early finalize call.
>>
>> Or am I reading it wrong?
> I think so. I don't think that the above paragraph, which begins "If
> these optimizations are allowed for references that are stored on the
> heap" in any way restricts optimization when references are on the
> stack. It only refers to the heap, and therefore it is not
> appropriate to read into it anything about references on the stack.
>
>>>> Probably the real issue is when the stack of the previous frame is
>>>> cleared, at the start of invoke(virtual) or at the end of
>>>> invoke(virtual)?
>>> I'm looking at the example at https://www.ibm.com/developerworks/forums/message.jspa?messageID=14915477
>>>
>>> Is that what you're talking about?
>> Yes, specifically the code I wrote at
>> https://www.ibm.com/developerworks/forums/message.jspa?messageID=14915477#14915477.
>>
>>> You say
>>>
>>>> 1. The current frame holds this in variable #0. While technically it
>>>> is possible to set local variable #0 to null, I find that an
>>>> extremely dirty action.
>>> But the specification explicitly allows it.
>> Yup, which I personally find a dirty action. :-)
>> Anyway it might warrant an extra warning in spec.
>>> And
>>>
>>>> 2. The previous frame is also holding a reference to FinalizeBug (or
>>>> at least should be ;-) ) in its stack.
>>> But the specification does not require it to do hold such a reference.
>>>
>> Where does it say that?
> In the explanatory text, it says
>
> "Optimizing transformations of a program can be designed that reduce
> the number of objects that are reachable to be less than those which
> would naively be considered reachable. For example, a Java compiler or
> code generator may choose to set a variable or parameter that will no
> longer be used to null to cause the storage for such an object to be
> potentially reclaimable sooner."
>
> It goes on to say:
>
> "Another example of this occurs if the values in an object's fields
> are stored in registers. The program may then access the registers
> instead of the object, and never access the object again."
>
> In my opinion, this example directly applies to your case. In work(),
> "this" is dead after this.set is read -- so the warning holds, and the
> finalizer may be invoked.
>
> Note that these are just examples: they don't limit what might happen,
> but merely warn about possible consequences.
>
> I do see this:
>
> "none of the pre-finalization reads of fields of that object may see
> writes that occur after finalization of that object is initiated."
>
> But this doesn't apply to your example: the invocation of set.clear()
> from FinalizeBug.finalize() doesn't affect any of the fields of
> FinalizeBug.
Right, which is why I'm talking about the conceptual state of
FinalizeBug, not the real state.
I fully admit that the code is purposely entering, what I would call, an
ill defined state. ;-)
>
>> Because as you can see it has serious implications for the conceptual
>> state of an object.
> I agree. The problem (if it is one) is that the definition of
> reachability is in some ways counter-intuitive, and Java programmers
> who rely on an intuitive understanding of it will eventually come to
> grief.
>
>> If it is by omission then either way it should explicitly stated it or
>> have an additional warning. (At least that's my opinion. :-) )
> I certainly agree that this should be discussed. Is the JLS the right
> place for such things, though?
Since the JLS defines reachability and when the finalize is run, I would
say yes.
Although the counter-argument would be that good programming practices
should not be in spec.
Then again the finalize guardian pattern did make it in. :-)
>
> The key phrase is this:
>
> "A reachable object is any object that can be accessed in any
> potential continuing computation from any live thread."
>
> So, the question is what constitutes an access. Is the execution of a
> method (of an object) after that method has been started an access to
> that object? I don't think it is.
>
> Andrew.
Understood, but can we assert this?
Carlo
More information about the java-se-8-spec-comments
mailing list