Return local object from function

S

Sean Hsien

Hi all,

I'm a newbie in Java. Was wondering what is the behaviour for the code
below:

myType obj = foo();

where the function foo() is defined below:

myType foo()
{
myType a = new myType();
...
return a;
}

What happens? Below are 3 alternatives that i can think of so far:
1. assignment be unsuccessful as the local object goes out of scope
once foo() ends
2. assignment is successful (copy ctor) before local object is cleaned
up from memory
3. assignment is successful and "obj" now points to same memory
location as "a"

Thanks and much appreciated.

Sean
 
S

Stefan Ram

Sean Hsien said:
1. assignment be unsuccessful as the local object goes out of
scope once foo() ends

Identifiers have scope, objects do not have scope.
2. assignment is successful (copy ctor) before local object is
cleaned up from memory

In Java, there is no »copy ctor«.
3. assignment is successful and "obj" now points to same memory
location as "a"

Yes.
 
M

Mark Space

Stefan said:
Identifiers have scope, objects do not have scope.

Just to add a bit more, recall that a local variable is allocated like this:

int methodName( int argument )
{
String s = new String();

That is, you must use "new." There's no way to put an object on the
stack. Primitives, yes (int, boolean, references, etc.), but not
objects. So you're guaranteed that any object is still on the heap when
a function exits.
In Java, there is no »copy ctor«.

Thank God.

It pretty much works like this in C:

int funcName( int argument )
{
char* s = calloc( 15, sizeof (char) );

except that s is reference counted and you don't have to worry about
free()ing it later. Isn't Java nice? I has the smart bits from C with
out the icky stuff.
 
M

Mike Schilling

Some simple rules:

* C++ pointers are called "references" in Java. There is nothing in Java
like a C++ reference.
* Local variables in Java are either scalars or references to objects
* There are no global variables. Static fields of Java classes are similar
to C++ globals, but they're explicitly allocated when the class is loaded,
not when the program starts up.
* Objects themselves are always dynamically allocated. .Thus, objects never
go out of scope.
* There is no such thing as explicit dealocation in Java (i.e.no delete
operator).
* Scalars and references are never dynamically allocated.
* Objects are made up of scalars and pointers. Unlike in C++, one object
never contains another.
 
O

Oliver Wong

Mark Space said:
[ No. ]

Just to add a bit more, recall that a local variable is allocated like
this:

int methodName( int argument )
{
String s = new String();

That is, you must use "new." There's no way to put an object on the
stack. Primitives, yes (int, boolean, references, etc.), but not objects.
So you're guaranteed that any object is still on the heap when a function
exits.

Some modern JVMs "intelligently" decided when to put an object on the
stack or heap for you, depending on what it predicts the code will do next.
The simplest way to express the rule is "Don't worry about objects
disappearing while you're still using them". It'll never happen, unless you
start doing fancy stuff with the WeakReference or SoftReference classes.

[...]
It pretty much works like this in C:

int funcName( int argument )
{
char* s = calloc( 15, sizeof (char) );

except that s is reference counted and you don't have to worry about
free()ing it later. Isn't Java nice? I has the smart bits from C with
out the icky stuff.

It doesn't nescessarily use reference counting. How the JVM does garbage
collection is implementation specific. So don't worry about stuff like
"Reference counting? Oh no! That means I have to avoid cyclic references!"
No, don't worry about that. Everything "just works" behind the scenes.

- Oliver
 
M

Mark Space

Oliver said:
Some modern JVMs "intelligently" decided when to put an object on the
stack or heap for you, depending on what it predicts the code will do
next. The simplest way to express the rule is "Don't worry about objects
disappearing while you're still using them". It'll never happen, unless
you start doing fancy stuff with the WeakReference or SoftReference
classes.

Right, good point. I'd read that in a discussion about Java garbage
collection and optimization, and I forgot about it. Conceptually, all
objects go on the heap. Really, there may be optimization when
possible, and small, local objects might be allocated somewhere besides
the heap.
It doesn't nescessarily use reference counting. How the JVM does
garbage collection is implementation specific. So don't worry about
stuff like "Reference counting? Oh no! That means I have to avoid cyclic
references!" No, don't worry about that. Everything "just works" behind
the scenes.

Also a good point. I think checking out info about Java garbage
collection would be a good idea. I remember reading about this, and
also the claim that modern garbage collectors where also faster than
most C++ de-allocation schemes, due to batching and performance analysis
at runtime.

But conceptually, it's like reference counting, in that objects go away
when the last reference to them disappears.
 
M

Mark Space

Mike said:
Some simple rules:

* C++ pointers are called "references" in Java.

Is this really true? I thought that Java references were 64 bits (8
bytes) on 32 bit systems, meaning that Java references are twice as big
as a pointer and there's therefore more going on in there than a simple
pointer.

Does anyone know what common JVM implementations stuff in a reference
besides just a pointer?
There is nothing in Java
like a C++ reference.

Well, I think references in Java are a lot like references in C++. :)
Java doesn't have the same operations on a reference that C++ does, but
the actual reference itself is similar and fulfills a similar purpose.

* There is no such thing as explicit dealocation in Java (i.e.no delete
operator).

I think you can force garbage collection in Java. Or fine tune it.

* Objects are made up of scalars and pointers. Unlike in C++, one object
never contains another.

Well, conceptually the reference is the object. References in Java can
be used for aggregation. But literally yes, Java doesn't make objects
contiguous in memory within another object.


Just my 2 bucks. I don't mind being wrong, sometimes I even learn
something.
 
O

Oliver Wong

Mark Space said:
Mike Schilling wrote:

I think you can force garbage collection in Java. Or fine tune it.

You can ask for garbage collection by calling System.gc(), but it's a
legal implementation for the JVM to ignore the request.

Some JVMs accept command line arguments so that you can select between
different flavours of garbage collectors.

- Oliver
 
M

Mike Schilling

Mark Space said:
Is this really true? I thought that Java references were 64 bits (8
bytes) on 32 bit systems, meaning that Java references are twice as big as
a pointer and there's therefore more going on in there than a simple
pointer.

There's no guarantee of the size of a pointer in either Java of C++.
Anyway, I'm talking about how they're used, not how they're implemented. If
you're a C++ programmer learning Java, you're better off thinking of them as
pointers.
Well, I think references in Java are a lot like references in C++. :)
Java doesn't have the same operations on a reference that C++ does, but
the actual reference itself is similar and fulfills a similar purpose.

The main thing that distnguishes a C++ reference from a C++ pointer is that
the reference can't be reset: it points to the same object for its entire
lifetime. This is not true of Java references. Likewise, Java references
can be null, while C++ references cannot.

Note that the exception that occurs when trying to dereference a Java
reference is a NullPointerException; they pretty clearly got renamed to
"reference" at some point.
I think you can force garbage collection in Java. Or fine tune it.

You can give the GC hints, with no guarantee they'll have any effect.
Unlike in C++, you cannot say "Tear down this specific object, now, and free
its memory." That's why, where it's very common to put cleanup logic in C++
destructors, it's uncommon to put similar logic in Java finalizers: because
there's no guarantee when (or whether) the finalizers will run.
Well, conceptually the reference is the object. References in Java can be
used for aggregation. But literally yes, Java doesn't make objects
contiguous in memory within another object.

Well, it might In Java, you don't really know anything about how things
are laid out in memory :)

In C++, when object B is contained inside A, their lifetimes are connected.
B is constructed as part of A's construction, and the same with destruction.
B cannnot be deleted except as a side-effect of deleting A. In Java, A can
point to B, but if something else points to B as well, B can outlive A.

That is C++ can both aggregate objects directly and make trees of objects
with pointers (or references). Java only has trees.
 
P

Patricia Shanahan

Mark said:
Right, good point. I'd read that in a discussion about Java garbage
collection and optimization, and I forgot about it. Conceptually, all
objects go on the heap. Really, there may be optimization when
possible, and small, local objects might be allocated somewhere besides
the heap.


Also a good point. I think checking out info about Java garbage
collection would be a good idea. I remember reading about this, and
also the claim that modern garbage collectors where also faster than
most C++ de-allocation schemes, due to batching and performance analysis
at runtime.

But conceptually, it's like reference counting, in that objects go away
when the last reference to them disappears.

An object can go away while there are still references to it, as long as
it cannot "be accessed in any potential continuing computation from any
live thread"

The distinction really does matter. Suppose objects x and y each have a
reference to the other, and that is the only reference to each of them.

A system in which objects go away when the last reference to them
disappears wound not be able collect either until the other has been
collected.

A Java implementation is allowed to note that both are unreachable, and
collect them both.

Patricia
 
M

Mark Space

Patricia said:
A Java implementation is allowed to note that both are unreachable, and
collect them both.

Right. The aforementioned cyclic references. This had been mentioned,
so I didn't touch on it.
 
C

Chris Uppal

Mark said:
Is this really true? I thought that Java references were 64 bits (8
bytes) on 32 bit systems, meaning that Java references are twice as big
as a pointer and there's therefore more going on in there than a simple
pointer.

Typical JVM implementations use raw pointers to implement Java's references --
i.e. 32-bits on a 32-bit machine

Does anyone know what common JVM implementations stuff in a reference
besides just a pointer?

Nowt.

FWIW, I haven't heard of /any/ JVM implementation which uses tagged pointers --
though I imagine that implementations which run on tagged hardware will do. In
fact I haven't heard of software-only tagging used for any language
implementation since Icon. Doesn't mean there aren't implementations I don't
know about, though...

-- chris
 
C

Chris Uppal

Mark said:
Really, there may be optimization when
possible, and small, local objects might be allocated somewhere besides
the heap.

AFAIK, that optimisation is not in the current Sun JVMs. There's a fair bit of
talk about such optimisations appearing in forthcoming releases, but I don't
know whether it's intended to make 1.6 -- nor how effective the implementation
will be in practise.

Also a good point. I think checking out info about Java garbage
collection would be a good idea. I remember reading about this, and
also the claim that modern garbage collectors where also faster than
most C++ de-allocation schemes, due to batching and performance analysis
at runtime.

It /ought/ to be faster -- for the simple reason that it gets used more, and so
should be the target of more performance work. But I suspect that the big
gains (if any, and rememberiing that there are losses too) is that the
design-space is expanded to include reduced-overhead program designs which
would be unmaintainable in C++.

But conceptually, it's like reference counting, in that objects go away
when the last reference to them disappears.

That could be misleading if it gives the impression that finalisation (in its
various flavours) will happen immediately or at a predictable time.

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top