~Destructor equivalent in java?

E

exquisitus

Hi ,

After I am done using an object, can I do the ff:

myObj = null ;

to flag it for collection of the heap by the GC?. Or (in this case)
since it is a local variable, do I assume that it will be trashed as
soon as it goes out of scope?. Which is the recommended method and why?

Thanks
 
O

Owen Jacobson

Hi ,

After I am done using an object, can I do the ff:

myObj = null ;

to flag it for collection of the heap by the GC?. Or (in this case) since
it is a local variable, do I assume that it will be trashed as soon as it
goes out of scope?. Which is the recommended method and why?

Thanks

You cannot in any way force the garbage collector to run or to collect an
object at any particular time from within the Java language.

Setting a reference to an object to null does nothing more than set the
reference to null. If that's the last reference, then the object is
eligible for GC, true, but may not be GCed right away (and, in Sun's
implementation, probably won't).
 
P

Peter MacMillan

exquisitus said:
Hi ,

After I am done using an object, can I do the ff:

myObj = null ;

Yes. Assuming that there are no other references to the object that was
pointed to by myObj, it will be available for garbage collection.
to flag it for collection of the heap by the GC?. Or (in this case)
since it is a local variable, do I assume that it will be trashed as
soon as it goes out of scope?. Which is the recommended method and why?


The object will become available for garbage collection as soon as there
are no references to it. When execution leaves the scope of, for
example, a method, local variables dissapear and their objects become
available for garbage collection (assuming that there are no other
references to the object).

In most cases, leaving it to the end of scope is sufficient for local
variables. For instance variables you'll probably want to set the
refrence to null. If your object refrences are in a collection (say a
vector or map), you'll definitly want to nullify the refrence.

Finally, objects are not garbage collected as soon as you nullify them
or when their references dissapear. They become availalbe and are
collected when the scheduler performs a collection. The time that this
happens is not really defined (but you may practically assume it happens
when it can).
 
E

exquisitus

Owen said:
You cannot in any way force the garbage collector to run or to collect an
object at any particular time from within the Java language.

Setting a reference to an object to null does nothing more than set the
reference to null. If that's the last reference, then the object is
eligible for GC, true, but may not be GCed right away (and, in Sun's
implementation, probably won't).
Thanks - but I don't think youve answered my question. Stated another
way, sgould I even bother setting objects to null after using them, or
shall I just leave them to go out of scope and get "alloced" memory to
get reclaimed by the GC?. Is there any difference in performance, is one
way more efecient than the other, or is there no difference (purely a
matter of personal preference/style)?

Whilst we are at it, is it true that declared (but not initialized)
objects are set to null by default (in which case I can do a check for
nulls without having made the assignement myself.

Also, is there a default value fo declared primitives and elements of an
Array of primitives/array of objects. Many questions, I appreciate your
patience - look forward to your response.

Thanks
 
A

Adam Maass

exquisitus said:
After I am done using an object, can I do the ff:

myObj = null ;

Yes, you can.
to flag it for collection of the heap by the GC?.

Assuming myObj was the last (or only) reference to the object, then the
object is now eligible for garbage collection.
Or (in this case) since it is a local variable, do I assume that it will
be trashed as soon as it goes out of scope?.

No. The variable itself (since it is local) will be trashed when the method
returns. (But no sooner in most VMs -- local lexical scopes are tricky in
this way.) The reference goes away. But an object with no references to it
is only "eligible for garbage collection" and in general, will not actually
be reclaimed immediately. Actual reclamation waits until a garbage
collection cycle happens. This cycle may never happen, depending on the
program and VM.
Which is the recommended method and why?

Assign "null" to a local reference variable if: 1) The object it refers to
itself large or holds large data, and 2) The current method will definitely
do more processing before returning. Otherwise, allow local variables to go
out of scope at method return; the objects they refer to will be garbage
collected as necessary. In either case, the collection will not necessarily
be immediate.


Note: there is no equivalent in Java to C++'s destructors. Implementing
"finalize()" looks similar but is not an exact equivalent, and there are
good reasons why this facility should not be used.
 
J

Joona I Palaste

exquisitus said:
After I am done using an object, can I do the ff:
myObj = null ;
to flag it for collection of the heap by the GC?. Or (in this case)
since it is a local variable, do I assume that it will be trashed as
soon as it goes out of scope?. Which is the recommended method and why?

Removing all references to an object is a necessary, but not sufficient,
requirement for it to be garbage collected. In other words, yes, you can
flag an object to be GC'd by setting all references to it to null. But
that doesn't mean it *will* be GC'd, at least not right away.
 
J

Joona I Palaste

Removing all references to an object is a necessary, but not sufficient,
requirement for it to be garbage collected. In other words, yes, you can
flag an object to be GC'd by setting all references to it to null. But
that doesn't mean it *will* be GC'd, at least not right away.

Sorry, that is confusing. By "removing all references" I did not
necessarily mean "explicitly setting all references to null". References
will also be removed if they go out of scope, or change to refer to some
other object.
 
T

Thomas G. Marshall

exquisitus coughed up:
Thanks - but I don't think youve answered my question. Stated another
way, sgould I even bother setting objects to null after using them, or
shall I just leave them to go out of scope and get "alloced" memory to
get reclaimed by the GC?.

In practice, you will sometimes see people explicitly null out a reference
so that reclamation occurs sooner than would otherwise happen. This is
usually only for large costly objects, or for large numbers of objects where
the sum total is excessive.

One thing that you can do is call System.gc(), which basically /asks/ the GC
to run the garbage collector if it feels like it. Here is what the docs
(1.5.0) say for it:

<quote>
Calling the gc method suggests that the Java
Virtual Machine expend effort toward recycling
unused objects in order to make the memory
they currently occupy available for quick reuse.
When control returns from the method call, the
Java Virtual Machine has made a best effort to
reclaim space from all discarded objects.
</quote>

This, however, is very misleading, in that it implies that the GC actually
is required to do something. As it turns out, the gc()'s "best effort"
could well be to do nothing at all, if its algorithm so chose.

Is there any difference in performance, is
one way more efecient than the other, or is there no difference
(purely a matter of personal preference/style)?

You /can/ see a difference, depending upon the vagaries of the algorithm.
However, actually controlling the thing is not an option. Most folks I know
of will experiment with nulling out references before they go out of scope,
but their results are hardly worth the exercise unless the objects memory
consumption is very large. There are run-time flags for modifying this
behavior as well, but I've never had to use them.

Whilst we are at it, is it true that declared (but not initialized)
objects are set to null by default (in which case I can do a check for
nulls without having made the assignement myself.
Yes.


Also, is there a default value fo declared primitives and elements of
an Array of primitives/array of objects.

Null for objects. 0 for primitives.

Many questions, I appreciate
your patience - look forward to your response.

Thanks


--
Unix users who vehemently argue that the "ln" command has its arguments
reversed do not understand much about the design of the utilities. "ln
arg1 arg2" sets the arguments in the same order as "mv arg1 arg2".
Existing file argument to non-existing argument. And in fact, mv
itself is implemented as a link followed by an unlink.
 
T

Thomas G. Marshall

Adam Maass coughed up:
Yes, you can.


Assuming myObj was the last (or only) reference to the object, then
the object is now eligible for garbage collection.


No. The variable itself (since it is local) will be trashed when the
method returns. (But no sooner in most VMs -- local lexical scopes
are tricky in this way.)

In what way is this tricky? If something's on the stack, it's on the stack.
If a method returns, that part of the stack frame goes away. Same as with
most languages. No?


....[rip]...
 
A

Adam Maass

Thomas G. Marshall said:
Adam Maass coughed up:

In what way is this tricky? If something's on the stack, it's on the
stack. If a method returns, that part of the stack frame goes away. Same
as with most languages. No?


Example:

void method() {
int i = 0;

{
float f = 0.0f;

}


}


In most (all?) VMs, the variable 'f' will not be cleared from the stack
until the end of the method, even though it goes out of scope sooner. That
was the point I was trying to make.
 
K

knightowl

You cannot in any way force the garbage collector to run or to
collect an
object at any particular time from within the Java language.

I was under the impression that System.gc(); would force the GC to run.

HFC
 
O

Owen Jacobson

I was under the impression that System.gc(); would force the GC to run.

System.gc () suggests that the GC run. The GC is not required to do
either a partial or full collection cycle, and may do nothing at all if
it's so inclined.
 
T

Thomas G. Marshall

Adam Maass coughed up:
Example:

void method() {
int i = 0;

{
float f = 0.0f;

}


}


In most (all?) VMs, the variable 'f' will not be cleared from the
stack until the end of the method, even though it goes out of scope
sooner. That was the point I was trying to make.

I thought this might be what you meant. How did you find this out?
 
T

Thomas G. Marshall

Owen Jacobson coughed up:
System.gc () suggests that the GC run. The GC is not required to do
either a partial or full collection cycle, and may do nothing at all
if it's so inclined.

Right. Which is why I am bothered by the fact that sun has never found a
better way to word this:

From System.gc() doc:
When control returns from the method call,
the Java Virtual Machine has made a best
effort to reclaim space from all discarded
objects.

....in Runtime.gc() doc, substitute "a best effort" with "its best effort".

This (both docs) only mean that part of its best attempt is to follow its
internal algorithm which might mean that its best attempt is nada nothing
zip.

This really should have been better worded, because it is terribly
misleading.
 
P

Patricia Shanahan

Thomas said:
Adam Maass coughed up:



I thought this might be what you meant. How did you find this out?

Here's a quick test:

public class TestScope {

public static void main(String[] args) {
System.out.println("Before call "+getMem());
memTest();
System.out.println("After call "+getMem());
}

static void memTest(){
System.out.println("Before block "+getMem());
{
System.out.println("Before allocation "+getMem());
double[] d = new double[1000000];
System.out.println("After allocation "+getMem());
}
System.out.println("After block "+getMem());
}

static long getMem(){
Runtime r = Runtime.getRuntime();
System.gc();
return r.totalMemory()-r.freeMemory();
}
}

Output (jdk1.4):

Before call 98008
Before block 98096
Before allocation 98192
After allocation 8097960
After block 8098048
After call 97936

The approximately 8 million bytes for the array are still in
use at "After block", although d is already out of scope.
They are free again after return from memTest, at "After call".

Note the use of System.gc() in getMem. If I comment it out,
I get:

Before call 161032
Before block 161032
Before allocation 161032
After allocation 8108600
After block 8108600
After call 8108600

Patricia
 
R

Reply7471859353

knightowl said:
I was under the impression that System.gc(); would force the GC to run.

HFC

~Destructor equivalent in java?

There isn't /any/ equivalent of physical ( processor object) memory
management within the Java language other than create object ( and
allocate physical memory for the object) thru Java's 'new' object
command.

This does not, necessarily, imply that FORTH and C languages are "best"
for writing physical memory object access programs. Java can develop
real time programs where all ( non-local stack) objects are statically
mapped ( by design) or develop language compilers and linkers for cross
targeting (any?) microprocessor machine code.

However,

***WARNING*** FAILURE TO PERFORM THE FOLLOWING MAY RESULT IN
A JAVA VIRTUAL MACHINE CRASH OR LOSS OF FUNCTION:


public static synchronized ShortArrayObj[] getMem(short machineid,
short size) {
try {
return tryGetMem( machineid, size)
}
catch ( OutOfMemoryError e ) {
/* destroy temporaries here */
for( short i=0; i < SMP_SIZE; i++)
MemMap = null;
System.gc();
/* re-create temporaries here */
for( short i=0; i < SMP_SIZE; i++)
MemMap = new Hashtable();
return tryGetMem(machineid, size, ... )
}
}


maw
 
A

Adam Maass

Thomas G. Marshall said:
Adam Maass coughed up:

I thought this might be what you meant. How did you find this out?

It's a consequence of the JVM's local variable model. Enough space on the
stack is allocated for all local variables in the method -- including those
declared in sub-blocks (and that go out of scope before the end of the
method).
 
L

Lee Fesperman

Adam said:
It's a consequence of the JVM's local variable model. Enough space on the
stack is allocated for all local variables in the method -- including those
declared in sub-blocks (and that go out of scope before the end of the
method).

Not quite. The compiler (Sun's at least) will reuse slots between subsequent sub-blocks
(those not enclosing each other).

This was discussed a while back in this group.
 
J

John C. Bollinger

Lee said:
Adam Maass wrote:
[...]
It's a consequence of the JVM's local variable model. Enough space on the
stack is allocated for all local variables in the method -- including those
declared in sub-blocks (and that go out of scope before the end of the
method).


Not quite. The compiler (Sun's at least) will reuse slots between subsequent sub-blocks
(those not enclosing each other).

Yes indeed, and that's all the more reason to take Adam's original
statement to heart: "local lexical scopes are tricky in this way."
 
L

Lee Fesperman

John said:
Lee said:
Adam Maass wrote:
[...]
It's a consequence of the JVM's local variable model. Enough space on the
stack is allocated for all local variables in the method -- including those
declared in sub-blocks (and that go out of scope before the end of the
method).


Not quite. The compiler (Sun's at least) will reuse slots between
subsequent sub-blocks (those not enclosing each other).

Yes indeed, and that's all the more reason to take Adam's original
statement to heart: "local lexical scopes are tricky in this way."

Agreed. I believe the purpose of that compiler optimization is to reduce stack space,
not to improve reachability behavior. Best practice is to assume that all local
variables are reachable until the method returns.
 

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

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top