Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

visibility of new object memory state

6 views
Skip to first unread message

Joe Seigh

unread,
Apr 7, 1998, 3:00:00 AM4/7/98
to

Consider the following java statement

x = new SomeObject();

where x is a variable with unsynchronized multi-thread
visibility. According to the jvm spec, the statement
roughly breaks down to the following steps.

1) allocate object from heap
2) initialize fields to default values for field type
3) invoke class init methods
4) store object reference in x

The jvm spec does not specify any memory visibility rules, so
in theory a thread other than the one doing the initialization
could observe the fields in the object before they've been
been initialized (actually, the reads could occur before the
writes from initialization completed).

Since a reference field not having a valid reference value
would violate a basic premise of Java, we can assume this
would never occur or would be otherwise fixed. So the
initialization steps should then be

1) allocate object from heap
2) initialize fields to valid values
3) sync memory
4) initialize fields to default values for field type
if step 2 did not use default values
5) invoke class init methods
6) store object reference in x

The question is, is it possible that an implementation would
use anything other than the default values in step 2? It
would be nice to be able to assume that for new objects
we would never be able to see anything other than the
default values or a value set by one of the init methods.

Joe Seigh

Michael Sinz

unread,
Apr 7, 1998, 3:00:00 AM4/7/98
to

Joe Seigh wrote:
>
> Consider the following java statement
>
> x = new SomeObject();
>
> where x is a variable with unsynchronized multi-thread
> visibility. According to the jvm spec, the statement
> roughly breaks down to the following steps.
>
> 1) allocate object from heap
> 2) initialize fields to default values for field type
> 3) invoke class init methods
> 4) store object reference in x
>
> The jvm spec does not specify any memory visibility rules, so
> in theory a thread other than the one doing the initialization
> could observe the fields in the object before they've been
> been initialized (actually, the reads could occur before the
> writes from initialization completed).

How would this happen? Since the reference "x" is not set until
after the init methods are run, there is reasonable way another
thread could "find" this new object before all init methods
are done. The specific instance of the object is only known
at this time to the constructors themselves. (Which could
be a problem if you code your constructor to give a reference
of "this" to someone else but that is not something the language
can solve...)

--
Michael Sinz -- Director of Research & Development, NextBus Inc.
mailto:michae...@nextbus.com --------- http://www.nextbus.com

Joe Seigh

unread,
Apr 7, 1998, 3:00:00 AM4/7/98
to

In article <352A3AA6...@sinz.org>, Michael Sinz <Mic...@sinz.org> writes:
|> Joe Seigh wrote:
|> >
|> > Consider the following java statement
|> >
|> > x = new SomeObject();
|> >
|> > where x is a variable with unsynchronized multi-thread
|> > visibility. According to the jvm spec, the statement
|> > roughly breaks down to the following steps.
|> >
|> > 1) allocate object from heap
|> > 2) initialize fields to default values for field type
|> > 3) invoke class init methods
|> > 4) store object reference in x
|> >
|> > The jvm spec does not specify any memory visibility rules, so
|> > in theory a thread other than the one doing the initialization
|> > could observe the fields in the object before they've been
|> > been initialized (actually, the reads could occur before the
|> > writes from initialization completed).
|>
|> How would this happen? Since the reference "x" is not set until
|> after the init methods are run, there is reasonable way another
|> thread could "find" this new object before all init methods
|> are done. The specific instance of the object is only known
|> at this time to the constructors themselves. (Which could
|> be a problem if you code your constructor to give a reference
|> of "this" to someone else but that is not something the language
|> can solve...)

While the store of the reference to the new object into variable x
occurred after the stores to the fields in the new object, the writes
do not necessarily have to occur in that order.

Also, it not true that a read of fields with an object have to occur
after the read of the reference to that object. You could have a
speculative java virtual machine or processor (the more likely case),
one that perform operations before it is known that they are really
necessary so that by the time it is known, they've already been done,
gaining a huge performance advantage. The jvm spec does not forbid
speculative fetches of variables.

So, since both read and writes can be out of order, there are two
places accessing an object through a stored reference to it could
break. But in the case of new objects, we can assume there are no
pre-existing references by the other threads to cause any speculative
pre-fetching, so we're only talking about one place where memory
barriers are required. Unless we are willing to contemplate a really
bizarre speculative jvm that performs fetchs from objects that the
current thread has no references to.

To illustrace the unsynchronized passing of an object from one
thread to another by the store an fetch of a reference to it.

thread 1
z.a = 1; // update field a in object
// write memory barrier required
x = z; // x is a global variable

thread 2
y = x;
// read memory barrier required
b = y.a; // access field a in object

As I've stated, I don't believe the read memory barrier is
required for new objects, but the write memory barrier definitely
is required.

Joe Seigh

Will Wood

unread,
Apr 7, 1998, 3:00:00 AM4/7/98
to Joe Seigh

Joe Seigh wrote:
> The jvm spec does not specify any memory visibility rules, so
> in theory a thread other than the one doing the initialization
> could observe the fields in the object before they've been
> been initialized (actually, the reads could occur before the
> writes from initialization completed).

Since Threads don't have direct visibility to the Address Space, the
reference to a new Object would have to be given out from the code
thread that allocated the Object. Thread X, unless informed won't
be able to see Thread Y's Object's unless the Reference of Y's Objects
are handed to Thread X somehow. So, from that standpoint you wouldn't
have to worry about another thread possibly receiving corrupted
information from initialization. However, if Thread X and Y both
have references to the same Object, then both of them are free to
act upon the Object's Methods as required. Without proper
synchronization there's no guarantee that the state of the Object will
be usable. This doesn't hold true for Immutable Objects such as Strings
which only return new Instances of Strings, or information about
the same String.

Patricia Shanahan

unread,
Apr 8, 1998, 3:00:00 AM4/8/98
to

No Java code, regardless of the thread in which it is running, should
be able to refer to the new object until after its constructor has
returned and supplied the reference to its caller, which in this case
would then assign the new reference to x. Until then, x is still null
or a reference to a previously created object, and there is no way for
this thread to tell any other thread about the object.

The problem you describe does exist, and is covered in the JLS, for
Class objects because two or more threads can independently start
creating objects of the same class at the same time.

Patricia

Joe Seigh wrote:
>
> Consider the following java statement
>
> x = new SomeObject();
>
> where x is a variable with unsynchronized multi-thread
> visibility. According to the jvm spec, the statement
> roughly breaks down to the following steps.
>
> 1) allocate object from heap
> 2) initialize fields to default values for field type
> 3) invoke class init methods
> 4) store object reference in x
>

> The jvm spec does not specify any memory visibility rules, so
> in theory a thread other than the one doing the initialization
> could observe the fields in the object before they've been
> been initialized (actually, the reads could occur before the
> writes from initialization completed).
>

> Since a reference field not having a valid reference value
> would violate a basic premise of Java, we can assume this
> would never occur or would be otherwise fixed. So the
> initialization steps should then be
>

> 1) allocate object from heap

David Holmes

unread,
Apr 8, 1998, 3:00:00 AM4/8/98
to

Joe Seigh <se...@bose.com> wrote in article <1998Apr...@bose.com>...

> The jvm spec does not specify any memory visibility rules, so
> in theory a thread other than the one doing the initialization
> could observe the fields in the object before they've been
> been initialized (actually, the reads could occur before the
> writes from initialization completed).

Joe, you always come up with such interesting questions. :)

I think this may well be "undefined" at present. The construction and
initialisation of objects is not described with regard to the thread
working memory model. So (for the benefit of those who don't understand how
this can occur) the initialisation of the new object must occur in the
current threads working memory before 'x' is assigned in the threads local
memory, but the order in which those values are written to main memory is
not predetermined by the thread memory model.

The implication is that memory write barrier instruction is needed after
object construction but before the reference is returned.

David

David Byrden

unread,
Apr 8, 1998, 3:00:00 AM4/8/98
to

David Holmes <dho...@mri.mq.edu.au> wrote in article
<01bd62b1$483e7c70$1bf56f89@dholmes>...

> Joe Seigh <se...@bose.com> wrote in article <1998Apr...@bose.com>...
> > The jvm spec does not specify any memory visibility rules, so
> > in theory a thread other than the one doing the initialization
> > could observe the fields in the object before they've been
> > been initialized (actually, the reads could occur before the
> > writes from initialization completed).

> I think this may well be "undefined" at present. The construction and
> initialisation of objects is not described with regard to the thread
> working memory model.


To be specific; it says somewhere that
by the time another thred can get access to an
object, its constructor will have returned,
because that's when the reference becomes
available. I can't find any explanation of what
will happen if the constructor passes 'this' to
another thread.


David


Michael Sinz

unread,
Apr 8, 1998, 3:00:00 AM4/8/98
to

Joe Seigh wrote:
>
> In article <352A3AA6...@sinz.org>, Michael Sinz <Mic...@sinz.org> writes:
> |> Joe Seigh wrote:
> |> >
> |> > Consider the following java statement
> |> >
> |> > x = new SomeObject();
> |> >
> |> > where x is a variable with unsynchronized multi-thread
> |> > visibility. According to the jvm spec, the statement
> |> > roughly breaks down to the following steps.
> |> >
> |> > 1) allocate object from heap
> |> > 2) initialize fields to default values for field type
> |> > 3) invoke class init methods
> |> > 4) store object reference in x
> |> >
> |> > The jvm spec does not specify any memory visibility rules, so
> |> > in theory a thread other than the one doing the initialization
> |> > could observe the fields in the object before they've been
> |> > been initialized (actually, the reads could occur before the
> |> > writes from initialization completed).
> |>
> |> How would this happen? Since the reference "x" is not set until
> |> after the init methods are run, there is reasonable way another
> |> thread could "find" this new object before all init methods
> |> are done. The specific instance of the object is only known
> |> at this time to the constructors themselves. (Which could
> |> be a problem if you code your constructor to give a reference
> |> of "this" to someone else but that is not something the language
> |> can solve...)
>
> While the store of the reference to the new object into variable x
> occurred after the stores to the fields in the new object, the writes
> do not necessarily have to occur in that order.

I think that there is a block in the constructor... Or the return
from a constructor. I would have to go back to the spec to find it
(I don't tend to memorize things anymore)

> Also, it not true that a read of fields with an object have to occur
> after the read of the reference to that object. You could have a
> speculative java virtual machine or processor (the more likely case),
> one that perform operations before it is known that they are really
> necessary so that by the time it is known, they've already been done,
> gaining a huge performance advantage. The jvm spec does not forbid
> speculative fetches of variables.

Interesting - so, a JVM could assign the result before it knew if it
worked and then "unassign" it if an exception happened. The question
here would be what are the rules about speculative results and their
visibility. Normally speculative execution results are considered an
internal optimization (hardware or software) and are not visible to
other parts/threads until the result is known to be correct. I do not
think that the JVM spec specifically covered this case but I would
think that they would assume standard practice for speculative results
and speculative execution.

> So, since both read and writes can be out of order, there are two
> places accessing an object through a stored reference to it could
> break. But in the case of new objects, we can assume there are no
> pre-existing references by the other threads to cause any speculative
> pre-fetching, so we're only talking about one place where memory
> barriers are required. Unless we are willing to contemplate a really
> bizarre speculative jvm that performs fetchs from objects that the
> current thread has no references to.
>
> To illustrace the unsynchronized passing of an object from one
> thread to another by the store an fetch of a reference to it.
>
> thread 1
> z.a = 1; // update field a in object
> // write memory barrier required
> x = z; // x is a global variable
>
> thread 2
> y = x;
> // read memory barrier required
> b = y.a; // access field a in object
>
> As I've stated, I don't believe the read memory barrier is
> required for new objects, but the write memory barrier definitely
> is required.

The thread 1 example has two statements that can have no ordering
requirements as far as final optimization. A JIT may reorder the
statements because it noticed that it could load the object pointer
and then set the value and finally store the pointer and have that
be pipelined into two clock ticks on a Pentium-II or 1.5 clocks (with
a open slot at the start) on an Alpha.

Plus, using this as is, without some thread synchonization is a sure
way to have problems since there is no way to know when the read of
X happens relative to the write of X. But that is not the issue here...

Michael Sinz

unread,
Apr 8, 1998, 3:00:00 AM4/8/98
to

David Byrden wrote:
>
> David Holmes <dho...@mri.mq.edu.au> wrote in article
> <01bd62b1$483e7c70$1bf56f89@dholmes>...
>
> > Joe Seigh <se...@bose.com> wrote in article <1998Apr...@bose.com>...
> > > The jvm spec does not specify any memory visibility rules, so
> > > in theory a thread other than the one doing the initialization
> > > could observe the fields in the object before they've been
> > > been initialized (actually, the reads could occur before the
> > > writes from initialization completed).
>
> > I think this may well be "undefined" at present. The construction and
> > initialisation of objects is not described with regard to the thread
> > working memory model.
>
> To be specific; it says somewhere that
> by the time another thred can get access to an
> object, its constructor will have returned,
> because that's when the reference becomes
> available. I can't find any explanation of what
> will happen if the constructor passes 'this' to
> another thread.

I think that passing 'this' from a constructor to another
thread is a very "iffy" issue. You could actually get
the other thread to do methods on your object before
a subclass had its constructor run or complete. Or, even
worse, the subclass may fail the constructor (throwing
an exception) but yet a reference exists elsewhere.

There are *many* problems with things like this. One of
the reasons why Thread does not start() itself during the
constructor. (Which effectively is giving 'this' to the
thread scheduler)

David Widjaja

unread,
Apr 9, 1998, 3:00:00 AM4/9/98
to

Did anybody ever try to use MFC in java (using "System.loadLibrary") ???

I am trying to make my own Window/Frame and MDI using MFC, instead of
using JFC("swing"), since it's slow and buggy. As matter of fact, I want
to make my own classes, instead of using JFC.

David Widjaja
dwid...@eatel.net


Mad Bob

unread,
Apr 9, 1998, 3:00:00 AM4/9/98
to

On Thu, 09 Apr 1998 12:36:33 -0500, David Widjaja <dwid...@eatel.net>
wrote:

>Did anybody ever try to use MFC in java (using "System.loadLibrary") ???
>
>I am trying to make my own Window/Frame and MDI using MFC, instead of
>using JFC("swing"), since it's slow and buggy. As matter of fact, I want
>to make my own classes, instead of using JFC.

You can do that and it works. But if you using Java for Windows
development, you better migrate to WFC.
-----------------------------------------------------------
Mad Bob,
Neither Sun nor Microsoft Certified Java Programmer.
Much fun under sun.

Joe Seigh

unread,
Apr 10, 1998, 3:00:00 AM4/10/98
to

In article <01bd62b1$483e7c70$1bf56f89@dholmes>, "David Holmes" <dho...@mri.mq.edu.au> writes:
|> Joe Seigh <se...@bose.com> wrote in article <1998Apr...@bose.com>...
|> > The jvm spec does not specify any memory visibility rules, so
|> > in theory a thread other than the one doing the initialization
|> > could observe the fields in the object before they've been
|> > been initialized (actually, the reads could occur before the
|> > writes from initialization completed).
|>
|> Joe, you always come up with such interesting questions. :)
|>
|> I think this may well be "undefined" at present. The construction and
|> initialisation of objects is not described with regard to the thread
|> working memory model. So (for the benefit of those who don't understand how
|> this can occur) the initialisation of the new object must occur in the
|> current threads working memory before 'x' is assigned in the threads local
|> memory, but the order in which those values are written to main memory is
|> not predetermined by the thread memory model.
|>
|> The implication is that memory write barrier instruction is needed after
|> object construction but before the reference is returned.

It turns out that a new object with all of its fields initialized to
their default values is not so very interesting from a programming
point of view. Since you'd have to use explicit synchronization
anyway to sync the memory state after the init methods have run, the
issue of an object's initial memory state doesn't exist for
programming. The issue is still a java security or integrity issue
however.

The other issue I brought up in this thread as to whether the value
of a field from a object could be read from memory before the pointer
or reference to the object was read from memory, a seemingly logical
paradox, it's possible. I went and rechecked the jvm specs. You are
allowed to cache the results of a prior read, so it is definitely
possible. You don't have to posit some hypothetical exotic
speculative java processor in order to be able to entertain this
possibility.

Joe Seigh

David Holmes

unread,
Apr 14, 1998, 3:00:00 AM4/14/98
to

David Byrden <Da...@Byrden.com> wrote in article
<01bd62d2$adca1c40$1f867dc2@goyra>...

> To be specific; it says somewhere that by the time another thred can get

> access to an object, its constructor will have returned, because that's
when
> the reference becomes available.

The return of the constructor is not the issue. The constructor can have
returned but the memory subsystem may not yet have written the values of
the objects fields into main memory. If the reference returned from the
constructor is written to main memory ahead of those fields then it is
theoretically possible for another thread to see the fields with their
default values, not the ones set by the constructor.

From going through the spec there would seem to be a bit of a hole with
regard to how things get kicked off. The spec states that variables are
created in main memory, not in a threads working memory, and thus the very
first operation a thread must perform on a variable is a 'load'. This
implies that the process by which memory for an object is allocated and
initialised with defaults takes place 'outside' of any thread. Beyond that
however no specific mention of construction is made. If we assume that once
the default initialised object has been magically constructed in main
memory, the constructor is simply executed by the thread and obeys all the
memory model rules, then there is nothing to prevent the scenario described
above from occurring.

I again say that the implication from this is that a memory write barrier
is needed after the constructor completes but before the new reference is
returned.

David

0 new messages