• Post Reply Bookmark Topic Watch Topic
  • New Topic

To what extent i can trust 'new' operator

 
Chris Jebaraj
Ranch Hand
Posts: 34
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Guys!!

Hashtable htOptions = new Hashtable();

Can this statment make sure that some memory is allocated? What about the disk space went off or the VM running short of memory. Wont i get null for htOptions in that case.

All i am confused right now is, do we need to check null for htOptions after this statement. If it is C++, we need to check null as we cannot be sure whether memory is allocated for the variable.

Would anyone of you, please clear me this doubt. I may be wrong , if so please correct me.
 
David Harkness
Ranch Hand
Posts: 1646
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To me, this is one of the most gratifying aspects of working with Java, and any language with good exception handling built into the core language. The "new" operator will either return a valid reference to a completely initialized* object or throw an OutOfMemoryError. It will never return null as long as the JVM has passed the certification tests.

* There is one trick here when dealing with multithreading that I must admit I still don't fully understand. Apparently, under the current memory model, it is possible for the new operator to return the reference and for the reference to be stored in the variable before the constructor has completed. Here is how I understand it.I would think that you can solve this easily by returning a reference to a new object from a method and having the caller assign it to a variable that other threads can access. This way the thread that allocated the memory must also have completed the constructor before the method can return (from my understanding).

Therefore, the object must be fully constructed for its reference to be assigned to a variable seen by other threads, and the problem is avoided.

I'll point out that I've never seen this in ten years of Java coding, the latter six years dealing with multithreaded applications. But I tend to code defensively anyway, and of course, I never write bugs as I never do more work than I'm paid to do.

Then again, Mulder's always saying, "Trust no one." Who ya gonna trust?
[ April 28, 2005: Message edited by: David Harkness ]
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24213
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Chris Jebaraj:
If it is C++, we need to check null as we cannot be sure whether memory is allocated for the variable.


Note that this is no longer true in ISO standard C++; new throws a bad_alloc exception if it can't allocate memory. It's true that a custom new operator or a new_handler might change this behavior, but that's in the same category of offenses as throwing a exception in a destructor.
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by David Harkness:
I would think that you can solve this easily by returning a reference to a new object from a method and having the caller assign it to a variable that other threads can access. This way the thread that allocated the memory must also have completed the constructor before the method can return (from my understanding).


It's true that the thread must have completed the constructor, but it might still *look* to another thread as if it didn't. That is because threads are allowed to use memory local to the thread, and there is no guarantee on when other threads will get their memory updated, unless you use synchronization.
 
Warren Dew
blacksmith
Ranch Hand
Posts: 1332
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
David Harkness:

To me, this is one of the most gratifying aspects of working with Java, and any language with good exception handling built into the core language. The "new" operator will either return a valid reference to a completely initialized* object or throw an OutOfMemoryError.

This is also true for any respectable variant of C++, as Ernest already noted for ISO C++. In most flavors of C++, a null is returned instead of an exception being thrown only if the programmer has explicitly requested that behavior.

I would think that you can solve this easily by returning a reference to a new object from a method and having the caller assign it to a variable that other threads can access. This way the thread that allocated the memory must also have completed the constructor before the method can return (from my understanding).

Therefore, the object must be fully constructed for its reference to be assigned to a variable seen by other threads, and the problem is avoided.


I'm not sure exactly what you're hoping for here, but if initialization is done in the constructor, that initialization is never guaranteed to have executed, as constructors are not synchronized. This is why I don't use constructors in multithreaded Java code; instead, I have a private, empty constructor, a private, synchronized initialization method that explicitly initializes all data members, and a public factory function that calls both.

It's a pretty extreme form of defensive programming, but the issue here is that threads may behave differently on different platforms, and you can't test for platforms that may not exist yet. Better safe than sorry.
 
David Harkness
Ranch Hand
Posts: 1646
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My reading of the JLS 2nd edtion (note: doesn't cover JDK 1.5) section 17.6 is that before each unlock (end of synchronized method or block) the JVM is required to flush all changes to its local cache to main memory.

Thus, if your factory method uses synchronization (any lock will do),it shouldn't matter that the constructor isn't synchronized. Before releasing the lock, the thread will write out all assignments made in the constructor and any methods it calls to main memory.

First, is this correct? Second, how has JDK 1.5's new memory model changed this? I'll try to answer that second question later today, but I thought I'd throw it out there.

I think the reason I figured my previous "solution" would work is that I was stuck on thinking of a thread's local memory strictly as registers, assuming that the assignment of variables to registers would be local to each method.

This comes from my limited exposure to machine language (65C02 many years ago). Each function chose which registers to use without regard to any other function. At the start it would push the registers it was going to use on the stack, use the registers, and then restore them from the stack before returning. Time to read the JVM specification, perhaps.

[ Added JLS link ]
[ April 28, 2005: Message edited by: David Harkness ]
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by David Harkness:
Before releasing the lock, the thread will write out all assignments made in the constructor and any methods it calls to main memory.

First, is this correct?


That's my understanding, too. I'm not really an expert in this regard, though...


I think the reason I figured my previous "solution" would work is that I was stuck on thinking of a thread's local memory strictly as registers, assuming that the assignment of variables to registers would be local to each method.

This comes from my limited exposure to machine language (65C02 many years ago). Each function chose which registers to use without regard to any other function. At the start it would push the registers it was going to use on the stack, use the registers, and then restore them from the stack before returning. Time to read the JVM specification, perhaps.


I wouldn't except the specification to specify this, as I wouldn't expect it to be specified in a way that is specific to a platform having registers.

So, though your assumption possibly is valid for most of the currently common platforms, I wouldn't expect Java to make any guarantees in this regard.

I would be delighted if someone looked up the details, though...
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!