finalize method problem.

Hello Everyone,

I m having a very strange problem..for which i cant find what the problem could be..

the problem is that i m running a simple java class in which i have written a finalize method where i m deallocating certain stuff...now as i run the method from the IDE (visual age) it runs perfect..but why try running the same program through command prompt the finalize method never gets called and nothing is even printed and even no exception...the same thing runs perfectly in the ide and produces the desired result.

[550 byte] By [mfarhans] at [2007-9-26 2:36:56]
# 1

There is no guarantee when finalizers will run, or if they will ever run at all. In fact, having finalize methods can interfere with the garbage collector.

I'd strongly advise you not to use finalize methods, but rather provide a method named close() or dispose() or cleanUp() that performs any releasing of resources.

schapel at 2007-6-29 10:05:29 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...
# 2

> I'd strongly advise you not to use finalize methods,

> but rather provide a method named close() or dispose()

> or cleanUp() that performs any releasing of resources.

do you mean thhe GC will try to call these methods. Are these "reserved" method names? I know the dispose() method from JFRame, but never saw it elsewhere...

vincent

dupontv at 2007-6-29 10:05:29 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...
# 3

you can add a System shutdown hook, that will run the finalization by hand. Here's the code:// how to register a close hook.

Runtime.getRuntime().addShutdownHook( aThread );

// how to run the finalization by hand

System.runFinalization();

// how to mix the 2

final class FinalizerThread extends Thread {

// flag, so the hook is not added twice.

private static boolean registered;

// just to be sure nobody will create such a thread

private FinalizerThread() {}

// install the hook. install it only once.

public static void installHook() {

if ( registered ) return;

Runtime.getRuntime().addShutdownHook( new FinalizerThread() );

registered = true;

}

// runs finalizations.

public void run() {

System.runFinalization();

}

}

remu at 2007-6-29 10:05:29 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...
# 4
No, the method names close(), dispose(), or cleanUp() are not reserved names. But you should name it something that suggests what it does. Providing this method is far safer and easier than providing finalizers.
schapel at 2007-6-29 10:05:29 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...
# 5
> you can add a System shutdown hook And that only works when the application exits correct?So it might not be the best solution if someone expects finalize to run any other time.
jschell at 2007-6-29 10:05:29 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...
# 6

I agree strongly with schapel.

Don't use finalize. Don't rely on documented classes that suggest finalize will clean stuff for you (java.sql.*).

If close(), dispose(), cleanUp() is provided always explicitly call them. And call them in all execution paths that do not terminate the application - so if you catch an exception make sure to use finally.

jschell at 2007-6-29 10:05:29 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...
# 7
But dont u think that the finalize method should be called once the program gets completed..that is for freeing up all the resources occupied by that perticularprogram..?
mfarhans at 2007-6-29 10:05:30 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...
# 8
in that case u mean to say that i must be calling these methods(close() , dispose() or else) expicitly when the program is about to exit?..or how is it gonna work
mfarhans at 2007-6-29 10:05:30 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...
# 9

You can never (as several has pinpointed above) be shure whether or not a finalizer will run. And for the missing exceptions: exceptions thrown from finalizers are neither caught nor reported, so throwing an exception out of a finalizer could in the worst case corrupt the entire program caucing unpredictable behaviour when other threads tries to access the object (e.g. the GC thread)

Also the method System.runFinalization() does NOT guarantee that the finalizers are run! (It only increases the likelihood...) The only methods that "guarantee" this, are all deprecated.

The adviced way to go is to use explicite termination methods, like e.g. dispose. THe best way to use them is like:

// some code...

try

{

Graphics g = getGraphics();

// use graphics object

}

finally

{

g.dispose();

}

Then the resource allocation/freeing behaves very much like C++ destructors (wich are very different from finalizers in deed).

DanielBakkelund at 2007-6-29 10:05:30 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...
# 10
ok the whole make sense...but for my own understanding.....first of all...1.would the garbage collector be called when the program ends.(taking in consideration that a lot of objects have been instantiated which are occupying memory resources.)
mfarhans at 2007-6-29 10:05:30 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...
# 11

> schapel

> There is no guarantee when finalizers will run, or if they will ever run at all. In fact, > having finalize methods can interfere with the garbage collector.

>jschell

> I agree strongly with schapel.

Hello !!! Please for god sake Tell me why I should not rely on finalize. OKI agree it is not fixed when will it run but is not it true that whenever the Object will be Garbage Collected its finalize () method will be called?

May be the solution given by remu is 100% correct but why should I unnecessarily get into threads?

After all, I just want is some kind of cleanup. I do not bother when it would be called all I want is a call to this method whenever Garbage collector is collecting the object. (Really It does not bother me when the garbage collector would collect the object may be after a day, after a week or after a year or after some years I just want the finalize to get called whenever the object is collected.)

And schapel, why is it so?

> In fact, having finalize methods can interfere with the garbage collector.

How did you come to this conclusion? I mean irrespective of how deep I have tried exploring java Garbage collection mechanism and finalize() method. I never across any thing which could suggest me so

Please reply ASAP to enlighten me.

IrenicMan at 2007-6-29 10:05:30 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...
# 12
Remu:Can u elaborate further of who is gonna call the installhook() method and where exactly should it be called or if i wrong how is the whole scenario gonna work..can u provide certain details.
mfarhans at 2007-6-29 10:05:30 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...
# 13

you call the installHook method at the beginning of your program. first line of your main(String[] args) method.// old main code

public static void main( String[] args ) {

// your stuff here

}

// new main code

public static void main( String[] args ) {

FinalizerThread.installHook();

// still your same stuff here

}

remu at 2007-6-29 10:05:30 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...
# 14

Why don't you want to rely on finalization?

Read Effective Java. There's a story about a programmer who tries to rely on finalize, and got OutOfMemoryErrors. It turns out that on one particular JVM, the finalizer ran in a low-priority thread. Because the rest of the system used 100% of the CPU, the finalizers never got time to run, and therefore the memory for the objects waiting for finalization was not released.

Also, you don't know what thread the finalizer will run in. That makes it extremely difficult to write correct finalizers.

And, if someone subclasses a class with finalizers, they have to remember to call super.finalize() in a finally block, otherwise your finalizer may not run.

And if all the isn't enough, there's no guarantee that finalizers will run at all. Even if your finalizers work on your current JVM, that's no guarantee that they will work on other JVMs.

Really, truly, it's a Bad Idea (TM) to rely on finalizers. Just write a cleanup method for users of your class to call. It's far easier to do and is guaranteed to work.

schapel at 2007-6-29 10:05:30 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...
# 15

>Hello !!! Please for god sake Tell me why I should not rely on finalize

THe only reason I can think of for using finalize is because you have a resource that you wish to free for the system to use again. That is how the garbage collector works with memory.

HOWEVER, I know of no known resource which has the 'volume' that memory does. There is a lot of memory that is allocated in very small pieces. Sockets, pipes, threads, locks, database connections, jni C heap allocations, etc are all other resources which which will never have the number of resources possible that memory does. And the garbage collector is constructed to handle memory, not other resources. And, if a resource isn't really anything that has to be freed then why have a finalize at all? And if you have a resource that you can hang on to for a week, why free it at all - just keep it.

>May be the solution given by remu is 100% correct but why

>should I unnecessarily get into threads?

That solution only works if you absolutely must free a resource when the application exits. It will not help while the application is running. Using a file (creating one) as a lock might be an example. But it should not be used for any resource that the OS would clean up anyways.

> > In fact, having finalize methods can interfere with the garbage collector.

> How did you come to this conclusion? I mean irrespective of how

> deep I have tried exploring java Garbage collection.

At the very minimum it allows for the possibility that the object could become alive again. And that means that even though it might be collected again, finalize would never be called again.

jschell at 2007-7-1 2:22:57 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...
# 16

> 1.would the garbage collector be called when the

> program ends.(taking in consideration that a lot of

> objects have been instantiated which are occupying

> memory resources.)

The reason finalizers are not called when the VM exits is because all resources will be destroyed whether they are finalized or not. The OS will reclaim memory that it provided to the java runtime at exit, so you do not have to worry about memory leaks that occur because of premature termination. The only significant problem is if you are using a shared OS resource (like locking files as was mentioned before). The only reason they don't get cleaned up is that the OS has no idea what you are using them for. A file is a file - a persistent thing.

The long and the short of it is that VM termination is something that must be handled carefully - but relying on finalizers (or the system shutdown hook - since a fault in the VM will bypass this) won't get you there.

smiths at 2007-7-1 2:22:57 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...
# 17

Thanks jschell.

You gave me good idea of what I was missing. although i still have some faith in finalize() but now I know I surely need to test my classes on various JVMs.

Anyway, Thanks a lot.

regards,

Amit.

(ps : but frankly I still don't agree with these lines

> > In fact, having finalize methods can interfere with the garbage collector.

> At the very minimum it allows for the possibility that the object could become alive again. And that means that even though it might be collected again, finalize would never be called again.

>

I feel although It might become alive (!!) but just for calling finalize() and than its gone. so where is the question of another call to finalize() ? I hope by alive you don't mean all new object creation.

)

IrenicMan at 2007-7-1 2:22:57 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...
# 18

> I feel although It might become alive (!!) but just for calling finalize() and

> than its gone. so where is the question of another call to finalize() ?

> I hope by alive you don't mean all new object creation.

Since I don't use finalize I haven't verified this, but it is possible to set a reference to the object being finalized in the finalize method. This will prevent the gargabe collector from collecting it at that time. However, it will never call finalize again for that object again.

jschell at 2007-7-1 2:22:57 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...
# 19
Good Question!
cheehwa at 2007-7-1 2:22:57 > top of Java-index,Archived Forums,Portability & Platform Independence [Archive]...