finalize() question

J

Joona I Palaste

The recent messages about finalize() got me thinking about this...
I got the impression that when the GC sweeps up an object, it calls its
finalize() method. Now if this is true, what happens if the finalize()
method of an object adds a reference to that object to some other live
object? I find three possible outcomes:
(1) The original object won't be swept up after all,
(2) The reference will end up being a zombie, accessing which will
either throw an exception or cause an error in the whole VM, or
(3) Such a thing is forbidden entirely.
Which is it? Or am I wrong altogether about the GC calling finalize()?

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-------------------------------------------------------- rules! --------/
"A friend of mine is into Voodoo Acupuncture. You don't have to go into her
office. You'll just be walking down the street and... ohh, that's much better!"
- Stephen Wright
 
N

Nicky

The correct outcome is (1).
But the next time the object will be about to be garbage collected, finalize
will NOT be called again (according to the specification finalize() is never
called more than once).
This is why adding a reference to a object in finalize() is usually a bad
idea.

Nicky
 
M

Mike Schilling

Joona I Palaste said:
The recent messages about finalize() got me thinking about this...
I got the impression that when the GC sweeps up an object, it calls its
finalize() method. Now if this is true, what happens if the finalize()
method of an object adds a reference to that object to some other live
object? I find three possible outcomes:
(1) The original object won't be swept up after all,
(2) The reference will end up being a zombie, accessing which will
either throw an exception or cause an error in the whole VM, or
(3) Such a thing is forbidden entirely.
Which is it? Or am I wrong altogether about the GC calling finalize()?

1 is correct. The JLS discusses this in some detail: see
http://java.sun.com/docs/books/jls/second_edition/html/execution.doc.html#44760
 
T

Tony Morris

Joona I Palaste said:
The recent messages about finalize() got me thinking about this...
I got the impression that when the GC sweeps up an object, it calls its
finalize() method. Now if this is true, what happens if the finalize()
method of an object adds a reference to that object to some other live
object? I find three possible outcomes:
(1) The original object won't be swept up after all,
(2) The reference will end up being a zombie, accessing which will
either throw an exception or cause an error in the whole VM, or
(3) Such a thing is forbidden entirely.
Which is it? Or am I wrong altogether about the GC calling finalize()?

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-------------------------------------------------------- rules! --------/
"A friend of mine is into Voodoo Acupuncture. You don't have to go into her
office. You'll just be walking down the street and... ohh, that's much better!"
- Stephen Wright

An object will have it's finalize() method called when it is garbage
collected.
It is not guaranteed that an object will be garbage collected, ever.

1 is the correct answer - there are articles out there that demonstrate this
in more detail than the JLS.
 
S

sks

An object will have it's finalize() method called when it is garbage
collected.
It is not guaranteed that an object will be garbage collected, ever.

Is it definitely guaranteed that when an object is gc'ed, finalise will be
called ?
 
X

xarax

sks said:
Is it definitely guaranteed that when an object is gc'ed, finalise will be
called ?

Object.finalize() for a particular instance may
not be called:

1. When Object.finalize() was not overridden. The
default method does nothing, so it's alright not to
call it.

2. When the JVM is shutting down. If you definitely
want some code to execute before the JVM shuts down,
then put that code into a shutdown hook (not in the
finalize() method). You can hang a WeakReference
with a ReferenceQueue to an instance that needs
clean-up. If the instance gets GC'd, then the WeakReference
is posted to the ReferenceQueue. OTOH, if the JVM shuts
down, then your shutdown hook can clean-up any remaining
instances that weren't GC'd.

Shutdown hooks and reference queues are the way to go.
Avoid overriding finalize().
 
T

Tony Morris

sks said:
Is it definitely guaranteed that when an object is gc'ed, finalise will be
called ?

Yes.
However, it is not guaranteed that an object will ever be garbage collected.
Overriding finalize() is almost always a bad idea.
 
A

Andrea Desole

From what I've seen here I understand that an object can be reachable
and finalized. How is it supposed to be used, then? Should I check, for
every method, that the object hasn't been finalized? Wouldn't it be
better to finalize it when it's sure that it's not going to be used?
Sorry, I don't get it.
 
M

Michael Borgwardt

Andrea said:
From what I've seen here I understand that an object can be reachable
and finalized. How is it supposed to be used, then? Should I check, for
every method, that the object hasn't been finalized?

No, you just should misuse finalize() like that.
Wouldn't it be
better to finalize it when it's sure that it's not going to be used?

That's *exactly* what happens. The problem is that it's possible to
re-introduce the object to "might still be used" status *in* the finalize()
method.
 
M

Mike Schilling

Michael Borgwardt said:
No, you just should misuse finalize() like that.

That is you should *not* misuse finalize() like that (which I'm sure is what
Michael meant to type.)
That's *exactly* what happens. The problem is that it's possible to
re-introduce the object to "might still be used" status *in* the
finalize()
method.

As in

static List theList;

protected void finalize() {
theList.add(this); // This is a truly bad idea
}
 
G

Grant Wagner

Joona I Palaste said:
The recent messages about finalize() got me thinking about this...
I got the impression that when the GC sweeps up an object, it calls its
finalize() method. Now if this is true, what happens if the finalize()
method of an object adds a reference to that object to some other live
object? I find three possible outcomes:
(1) The original object won't be swept up after all,
(2) The reference will end up being a zombie, accessing which will
either throw an exception or cause an error in the whole VM, or
(3) Such a thing is forbidden entirely.
Which is it? Or am I wrong altogether about the GC calling finalize()?

<url: developer.java.sun.com/developer/
Books/performance/performance2/appendixa.pdf />

A.3.5 Collected
An object is in the collected state when the garbage collector has
recognized an object as unreachable and readies it for final processing
as a precursor to deallocation. If the object has a finalize method,
then it is marked for finalization. If it does not have a finalizer then
it moves straight to the finalized state. If a class defines a
finalizer, then any instance of that class must have the finalizer
called prior to deallocation. This means that deallocation is delayed by
the inclusion of a finalizer.

A.3.6 Finalized

An object is in the finalized state if it is still unreachable after its
finalize method, if any, has been run. A finalized object is awaiting
deallocation.

A.3.7 Deallocated

The deallocated state is the final step in garbage collection. If an
object is still unreachable after all the above work has occurred, then
it is a candidate for deallocation.


So the answer is (1) The original object won't be swept up after all
 

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,997
Messages
2,570,241
Members
46,830
Latest member
HeleneMull

Latest Threads

Top