Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #30485 > unrolled thread
| Started by | somenathpal@gmail.com |
|---|---|
| First post | 2014-12-04 08:56 -0800 |
| Last post | 2015-01-04 16:13 -0800 |
| Articles | 6 — 6 participants |
Back to article view | Back to comp.lang.java.programmer
finalize() not called. somenathpal@gmail.com - 2014-12-04 08:56 -0800
Re: finalize() not called. Robert Klemme <shortcutter@googlemail.com> - 2014-12-04 20:37 +0100
Re: finalize() not called. v_borchert@despammed.com (Volker Borchert) - 2014-12-04 19:05 +0000
Re: finalize() not called. Joshua Cranmer 🐧 <Pidgeot18@verizon.invalid> - 2014-12-04 14:24 -0600
Re: finalize() not called. Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-12-06 16:07 -0500
Re: finalize() not called. Lew <lewbloch@gmail.com> - 2015-01-04 16:13 -0800
| From | somenathpal@gmail.com |
|---|---|
| Date | 2014-12-04 08:56 -0800 |
| Subject | finalize() not called. |
| Message-ID | <850b3ab9-57ea-490c-a165-943183169841@googlegroups.com> |
I have the following class
public class Book {
boolean checkout = false;
public Book(boolean checkout) {
this.checkout = checkout;
}
void checkIn() {
checkout = false;
}
protected void finalize() {
if (checkout) {
System.out.println("Error Checked Out !!");
}
}
}
==========================================================================
And it is used as follows
public class Test {
public static void main(String[] args) {
Book novel =new Book(true);
novel.checkIn();
Book book = new Book(true);
//System.out.println("Calling GC");
System.gc();
}
}
Now when System.gc() is called I expect finalize() to be called. But it does not get called. But when I uncomment the following
System.out.println("Calling GC"); the finalize() gets called. I am not able to understand this behavior. I was expecting finalize() method yo be called.
Could you please explain the behavior.
[toc] | [next] | [standalone]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2014-12-04 20:37 +0100 |
| Message-ID | <cebrggFjgvoU1@mid.individual.net> |
| In reply to | #30485 |
On 04.12.2014 17:56, somenathpal@gmail.com wrote:
> Now when System.gc() is called I expect finalize() to be called. But it does not get called. But when I uncomment the following
> System.out.println("Calling GC"); the finalize() gets called. I am not able to understand this behavior. I was expecting finalize() method yo be called.
> Could you please explain the behavior.
That method is only ever invoked *if* "garbage collection determines
that there are no more references to the object".
http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#finalize()
First of all invoking System.gc() is not a guarantee that GC is actually
done.
http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#gc()
Second, even if GC is running there are no guarantees that all objects
are collected that may be collected.
If you need to do cleanup at a particular point then the usual pattern
in Java involves a try finally block. More recent versions of Java
provide additional means:
http://www.theserverside.com/tutorial/OCPJP-Exam-Objective-How-to-Use-Try-With-Resources-to-Clean-Up-Closeable-Resources
Kind regards
robert
[toc] | [prev] | [next] | [standalone]
| From | v_borchert@despammed.com (Volker Borchert) |
|---|---|
| Date | 2014-12-04 19:05 +0000 |
| Message-ID | <m5qb9j$45d$1@Gaia.teknon.de> |
| In reply to | #30485 |
somenathpal@gmail.com wrote:
> Now when System.gc() is called I expect finalize() to be called.
> But it does not get called. But when I uncomment the following
> System.out.println("Calling GC"); the finalize() gets called.
> I am not able to understand this behavior. I was expecting
> finalize() method yo be called.
RTFB (= Read The Fine Book ;-), in this case, "Effective Java"
item #7 (in the 2nd edition) on why finalizers have been a really
bead idea right from the beginning, but for reasons probably just
not yet understood all those years ago.
Basically, there are no guarantees as to when, on which thread, and
whether at all finalizers are called.
If you need to make sure that locks are released or resources freed,
put the release or free into finally blocks. If you are just curious
to know when objects are GCed, or want to do non-urgent bookkeeping
like eventually removing the map entries for GCed keys or values from
a cache, use PhantomReference in cunjonction with ReferenceQueue.
--
"I'm a doctor, not a mechanic." Dr Leonard McCoy <mccoy@ncc1701.starfleet.fed>
"I'm a mechanic, not a doctor." Volker Borchert <v_borchert@despammed.com>
[toc] | [prev] | [next] | [standalone]
| From | Joshua Cranmer 🐧 <Pidgeot18@verizon.invalid> |
|---|---|
| Date | 2014-12-04 14:24 -0600 |
| Message-ID | <m5qftc$uuu$1@dont-email.me> |
| In reply to | #30485 |
On 12/4/2014 10:56 AM, somenathpal@gmail.com wrote:
> Now when System.gc() is called I expect finalize() to be called. But
> it does not get called. But when I uncomment the following
> System.out.println("Calling GC"); the finalize() gets called. I am
> not able to understand this behavior. I was expecting finalize()
> method yo be called. Could you please explain the behavior.
Garbage collectors are very complex beasts, so all I can do is speculate
on the behavior.
A modern garbage collector is concurrent--it runs in a separate thread,
all the time. The point of the garbage collector is that it frees you
from worrying about when memory is freed--it is freed no earlier than it
could be freed. But that's not a tight constraint as to when the memory
will be freed (and tightly constraining that would destroy the
performance)--it will eventually happen.
When you call System.gc(), that is semantically an advisory to the
garbage collector that it should run. This effectively amounts to
posting an event to the GC to start a collection. Since your program
exits immediately afterwards, it's basically a race to see if the
finalizer is executed first or the program exits first.
finalize() is meant, primarily, for cleaning up resources (e.g., file
descriptors) if the instance wasn't closed before becoming dead code.
It's only a reliable as a "just-in-case someone forgot to do this, don't
leak," and not as a replacement for C++ destructors. If you need
destructor-like functionality, you really should be using the
try-resource blocks feature added in Java 7.
--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2014-12-06 16:07 -0500 |
| Message-ID | <m5vr5r$h2m$1@dont-email.me> |
| In reply to | #30485 |
On 12/4/2014 11:56 AM, somenathpal@gmail.com wrote:
> I have the following class
> public class Book {
> [...]
> protected void finalize() {
> if (checkout) {
> System.out.println("Error Checked Out !!");
> }
>
> }
> }
Others have explained why finalize() will not be called when
you expect. However, if you decide to implement finalize() for
this or any other class, you must obey its contract by ensuring
that the superclass' finalize() also runs:
protected void finalize() throws Throwable {
try {
if (checkout) {
System.out.println("Error Checked Out !!");
}
} finally {
super.finalize();
}
}
The try/finally block guarantees that super.finalize() will run
even if your own finalizer's operations throw an exception or
terminate abruptly. Also, since the superclass' finalize() can
throw any Throwable, your finalize() must also be declared as
throwing Throwable.
"Effective Java" by Joshua Bloch advises against implementing
finalize() at all, but shows how to do it properly (as above) and
even how to do it defensively (see the book) if you must. I'll
second Volker Borchert's recommendation that you read this book;
it's a good 'un.
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM
[toc] | [prev] | [next] | [standalone]
| From | Lew <lewbloch@gmail.com> |
|---|---|
| Date | 2015-01-04 16:13 -0800 |
| Message-ID | <239f937c-2c5e-4718-83af-a7cb19c38561@googlegroups.com> |
| In reply to | #30492 |
In the code snippet all relevant objects are still alive, so one would not expect GC to touch them, much less call 'finalize'.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web