By: Tzvetan Mikov (tzvetanmi.delete@this.yahoo.com), October 27, 2006 5:12 pm
Room: Moderated Discussions
Rob Thorpe (rthorpe@realworldtech.com) on 10/27/06 wrote:
---------------------------
>I've had a through look on the web. It seems that this issue has come up in the
>Java community. In particular William Pugh, Tim Lindholm and Doug Lea have looked at it.
>
>It seems that the original Java specs were vague on the issue we are discussing.
>Later it came to be accepted that it's possible for objects to be modified (due
>to reordering) before the constructor has completed! This is actually what happens
>in some JVMs. According to Pugh's page in the past JVMs on platforms with quite
>strong memory consistency still failed because of compiler optimizations people
>had put in without checking their validity.
>
>A JSR, number 133, has been written to change this behaviour. This JSR introduces
>the concept of "final" variables which solve the problem to some extent. JSR133
>will be fully implemented in Java 1.5 apparently, though some is in 1.4.
>
>This means current Javas are only really SAFE1 and future Javas will only be SAFE1
>too, unless all fields in objects are declared "final".
>
>See:-
>IBM developerworks article on the subject (see section on initialization safety)
>http://www-128.ibm.com/developerworks/java/library/j-jtp03304/
>
>Pugh's original description of the problem
>http://www.cs.umd.edu/~pugh/java/broken.pdf
>
>The draft JSR133 spec. See especially page 13 & 14 referring to this problem
>http://www.cs.umd.edu/~pugh/java/memoryModel/CurrentDraftSpec.pdf
>>
>
>The Java community process JSR133 page
>http://jcp.org/en/jsr/detail?id=133
>
The links are very informative, thanks. I've actually read JSR133 before, but I hadn't realized the extent of the problem particularly with respect to the object metadata/headers. It isn't really apparent that almost every non-local variable access conceptually requires a read barrier.
Most articles discussing this concentrate on final fields, which is a somewhat less interesting problem. Final fields aren't really "final" in Java - clearly they are normal variables and clearly they have values before they are initialized, not to mention that they can be modified by deserializing - so it isn't surprising at all that the original JMM didn't guarantee their values.
That seems pretty reasonable to me, and actually I don't think it breaks SAFE2. Unsynchronized access to a "final" variable could encounter a value of NULL, which has no danger of crashing the VM. It is a bug. It is silly to pretend that a final variable doesn't exist before it is initialized.
So, pre-JSR133 JVMs are SAFE2. (Otherwise they would crash).
In practice however lots of Java code (including some of the 1.4. library code aparently) is written with the assumption that final fields are completely immutable and safe for unsynchronized access. In that context it probably makes sense to make stronger guarantees about them in Java.
Personnaly, from a pure language design standpoint, I think that may be going too far.
---------------------------
>I've had a through look on the web. It seems that this issue has come up in the
>Java community. In particular William Pugh, Tim Lindholm and Doug Lea have looked at it.
>
>It seems that the original Java specs were vague on the issue we are discussing.
>Later it came to be accepted that it's possible for objects to be modified (due
>to reordering) before the constructor has completed! This is actually what happens
>in some JVMs. According to Pugh's page in the past JVMs on platforms with quite
>strong memory consistency still failed because of compiler optimizations people
>had put in without checking their validity.
>
>A JSR, number 133, has been written to change this behaviour. This JSR introduces
>the concept of "final" variables which solve the problem to some extent. JSR133
>will be fully implemented in Java 1.5 apparently, though some is in 1.4.
>
>This means current Javas are only really SAFE1 and future Javas will only be SAFE1
>too, unless all fields in objects are declared "final".
>
>See:-
>IBM developerworks article on the subject (see section on initialization safety)
>http://www-128.ibm.com/developerworks/java/library/j-jtp03304/
>
>Pugh's original description of the problem
>http://www.cs.umd.edu/~pugh/java/broken.pdf
>
>The draft JSR133 spec. See especially page 13 & 14 referring to this problem
>http://www.cs.umd.edu/~pugh/java/memoryModel/CurrentDraftSpec.pdf
>>
>
>The Java community process JSR133 page
>http://jcp.org/en/jsr/detail?id=133
>
The links are very informative, thanks. I've actually read JSR133 before, but I hadn't realized the extent of the problem particularly with respect to the object metadata/headers. It isn't really apparent that almost every non-local variable access conceptually requires a read barrier.
Most articles discussing this concentrate on final fields, which is a somewhat less interesting problem. Final fields aren't really "final" in Java - clearly they are normal variables and clearly they have values before they are initialized, not to mention that they can be modified by deserializing - so it isn't surprising at all that the original JMM didn't guarantee their values.
That seems pretty reasonable to me, and actually I don't think it breaks SAFE2. Unsynchronized access to a "final" variable could encounter a value of NULL, which has no danger of crashing the VM. It is a bug. It is silly to pretend that a final variable doesn't exist before it is initialized.
So, pre-JSR133 JVMs are SAFE2. (Otherwise they would crash).
In practice however lots of Java code (including some of the 1.4. library code aparently) is written with the assumption that final fields are completely immutable and safe for unsynchronized access. In that context it probably makes sense to make stronger guarantees about them in Java.
Personnaly, from a pure language design standpoint, I think that may be going too far.