2

Finalizers are not destructors, finalizers are useless.

From what I hear a lot of Java resource Objects dispose on finalize() "just in case".
This seems an overly permissive attitude likely to lead to bugs.

The least you would want to do is for finalize to log errors(un disposed resources at finalization time) and print them to standard out and then dispose.
A more restrictive attitude might be to thow an exception instead. I'm not necessarily going to implement such restrictive resource objects but I'd like to know how to do it.

But in Java an exception thrown in a finalizer gets ignored(other then the object being put back on the list to be finalized again). Is there a way to implement something like this? Maybe a way to give thread that created object an exception from the finalizer if it still exists(or possibly parent threads if not?

Also!!!!! How do other gc languages(especially C#,python and the like) deal with resource finalization(do they generally implement "just in case disposal" for resource classes?), throwing from finalizers, giving exeptions to other threads. (note: I don't care much about with/using sugar for calling dispose method or methods accepting closures that automatically close resource, I'm intrested in what role finalizers play and error propagation from finalizers).

Roman A. Taycher
  • 18,619
  • 19
  • 86
  • 141

2 Answers2

1

The finaliser is called in a dedicated thread so throwing an exception or error wouldn't achieve anything because you wouldn't be able to catch the exception in your code or one of your threads.

If you want to pass exceptions to another thread you can do this in any number of ways. However its not clear to me what you would do in another thread, that you would do in the current thread. i.e. why create an exception to pass to another thread to turn into log message when you could have the current thread log a message.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • You can call `System.exit(-1);` if that is what you want. Crashing is rarely the best option. – Peter Lawrey Sep 10 '11 at 11:18
  • Yeah I don't want to crash I was just hoping it would be possible to propogate exceptions so that it would crash in a traceback if and only ! if it wasn't handled, also it wouldn't get thrown unless object wasn't disposed before garbage collecting time. – Roman A. Taycher Sep 10 '11 at 11:25
  • It not clear to me where you want these exceptions to be propagated to. What do you gain by doing this which you cannot do in the finalizer? – Peter Lawrey Sep 10 '11 at 11:29
  • Not disposing before a finalizer is arguably an error I want to signal an error occurred. – Roman A. Taycher Sep 11 '11 at 06:03
  • 1
    I log an error that a component which should have been closed was instead discarded (as well as details about the component). I don't see the benefit in making it any more complicated than that. – Peter Lawrey Sep 11 '11 at 06:42
0

Finalizers in themselves have loads and loads and loads of disadvantages right from taking longer time for Object creation to not disposing the resources til the finalizer thread calls the finalize method to so on.

The only reason why one should use it is to take precaution to dispose resources say for example InputStream's have the method which results in close(), now this might never be called also. The other case when one must use it is while using native's. There is abolutely no other case when one should do it.

Now the problem with your desire to implement the above is that say: there is an object with a finalize() method. Now when there is no strong reference to the object, it is sent for Garbage Collection. Now it checks from its entry table, if this particular object has a finalize() method( which was noted when the object was created at the first place). Now when the finalizer thread runs the finalize() method, and inside this method there is a block of code which ultimately resulted in this method having a strong reference.

Next time when the same object is called for garbage collection, this object is not sent to finalizer queue the second time (by default as no object can goto finalizer queue more than once), hence the finalize() method is not called the second time. This might result in huge problem.

Hence if you are dealing with some thing, make sure you do it outside the finalize() method rather than doing it in finalize() as it only leads to problems and nothing else

Jatin
  • 31,116
  • 15
  • 98
  • 163
  • And have that thread propogate an exception to allocating thread? – Roman A. Taycher Sep 10 '11 at 10:49
  • can you pl be more specific? If you mean to have a block where other thread can have reference to this thread? That is absolutely highly dangerous for the same reason as explained before – Jatin Sep 10 '11 at 10:54
  • Or have some another method similar to t close() or dispose() method, which does the work of disposing resources etc. – Jatin Sep 10 '11 at 10:55
  • By the way: The two legitimate uses of finalizers mentioned above can also be read in Effective Java, Item 7: Avoid finalizers. – box Sep 10 '11 at 14:45