Saturday, 3 December 2016

Why should we avoid finalize method?

‘finalize’ method is defined in Object class, it is executed by JVM (java Virtual Machine) just before the object is being garbage collected. Sub classes can override this method and perform some relevant operation like cleaning up native resources. First let me explain an example of finalize method, after that we can discuss, why shouldn’t we use finalize method in our applications.

Connection.java
public class Connection {

 public Connection() {

 }

 public void close() {
  System.out.println("Connection is getting closed");
 }

 @Override
 public void finalize() throws Throwable {
  this.close();
  super.finalize();
 }

}

ConnectionTest.java
public class ConnectionTest {
 public static void main(String args[]) throws InterruptedException {
  Connection conn = new Connection();

  conn = null;
  Runtime.getRuntime().gc();
  
  Thread.sleep(3000);
 }
}

Output
Connection is getting closed


Why shouldn’t we use finalize method?
a.   One problem with finalizers is that, Java specification doesn't guarantees immediate execution of finalize method on object unreachable.

b.   The Java programming language does not specify which thread will invoke the finalizer for any given object. So it is completely dependent on implementation of specific java vendor. Some vendors may implement it as part of garbage collection thread (or) some may implement it as separate thread. Because of this, behavior of finalize method may change from one implementation to other.

c.    Finalizers can be called in any order. It is not necessary that they will be called in the order that objects are unreachable. The Java programming language imposes no ordering on finalize method calls.

d.   If an uncaught exception is thrown during the finalization, the exception is ignored and finalization of that object terminates.

Example
    @Override
    public void finalize() throws Throwable {
             this.close();
             String s = null;
             s.toCharArray();
             super.finalize();
    }

Notify above snippet, In ideal scenarios, Java run time throws NullPointerException while executing the statement 's.toCharArray();'. Since this statement is inside the finalize method, it will be ignored.

e.   "finalizer chaining" is not performed automatically. If a sub class overrides finalize method of super class, then the subclass finalizer must invoke the superclass finalizer manually.

f.    Don't close critical resources in finalize method. For example, if you are developing an application that works with files, always close the file handles after their usage. If you closed the file handles in finalize method. It is not guaranteed that they will be closed immediately. Even though you are done with the file usage, the handle still be in use, since finalize is not executed yet.

Is there any way that I can control the execution of finalize method?
System class provide 'runFinalization' method, when you call this method, Java Virtual Machine expend effort toward running the finalize methods of objects that have been found to be discarded but whose finalize methods have not yet been run.

You may like


No comments:

Post a Comment