6

Why execution of finalize() isn't guaranteed at all in Java? Is finalize() method shouldn't be used???

Consider below program.

class Test{
   protected void finalize()
   {
       System.out.println("Will i execute?");
   }
   public static void main(String args[])
   {
         Test t=new Test();
   }
}

There is an empty output when this program runs. We know that finalize() is used to cleanup any external resources before the object becomes eligible for garbage collection & finalize() will be called by JVM. Inside finalize() we will specify those actions that must be performed before an object is destroyed. Is finalize() method evil??

Subhrajyoti Majumder
  • 40,646
  • 13
  • 77
  • 103
Destructor
  • 14,123
  • 11
  • 61
  • 126
  • 4
    http://stackoverflow.com/questions/2506488/when-is-the-finalize-method-called-in-java – Hari Jul 25 '14 at 05:26
  • First, it is not evil. Second, finalize() gets called before GC reclaim the object. Third, your object is not heavy to get GC. Fourth, http://javarevisited.blogspot.com/2012/03/finalize-method-in-java-tutorial.html – Nikhil Joshi Jul 25 '14 at 05:26
  • Generally it's not a good idea to call finalize(). Joshua Block discusses the problems and when it may be Ok to use finalise() here http://www.informit.com/articles/article.aspx?p=1216151&seqNum=7. – fipple Jul 25 '14 at 05:30
  • TheLostMind and Hari have as good of an answer as any. Finializers are bad, stay away from them. Try to find an alternative, like [ReferenceQueue](http://docs.oracle.com/javase/7/docs/api/java/lang/ref/ReferenceQueue.html)s if you must, but the best option is not to do anything, just allow the object to be garbage collected. – markspace Jul 25 '14 at 05:30
  • I would say use `try {} finally {}` for freeing resources. usually implementing `finalize` is not required. – Shailesh Aswal Jul 25 '14 at 05:35

5 Answers5

3

finalize() is Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. .

You could use System.gc() to explicitly call for garbage collection and check if your statement gets printed. But the JVM has the liberty to ignore your request (depends on the JVM implementation actually..). Only when the JVM's internal state tells it that there is too much garbage and it needs to be collected, then it will run GC (and the line will I execute) will be printed.

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
  • 1
    It's not a precise answer: `finalize()` is a method that you can implement and it will be invoked by the VM when the VM has determined that your object has become unreachable. It's not a suggestion to the VM at all. – Erwin Bolwidt Jul 25 '14 at 05:34
  • @ErwinBolwidt - Ya.. edited it :) thanks. (sorry about misplaced and misleading statements..) – TheLostMind Jul 25 '14 at 05:35
3

Javadoc link, because many quotes will follow.

We know that finalize() is used to cleanup any external resources before the object becomes eligible for garbage collection

No. Once the object becomes eligible for garbage collection, then finalize() can get invoked. finalize could theoretically make the object no longer eligible for garbage collection and the garbage collector would then skip it. As stated

After the finalize method has been invoked for an object, no further action is taken until the Java virtual machine has again determined that there is no longer any means by which this object can be accessed by any thread that has not yet died

Why execution of finalize() isn't guaranteed at all in Java?

It is guaranteed to run. As the Javadoc states

The general contract of finalize is that it is invoked if and when the Java™ virtual machine has determined that there is no longer any means by which this object can be accessed by any thread that has not yet died, except as a result of an action taken by the finalization of some other object or class which is ready to be finalized.

What isn't guaranteed is when or if garbage collection will occur.

Should i use finalize() or not in java?

That depends on your use case. Start by reading the javadoc and understand the implications.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
1

If I understand your question, you can use the System.gc() to request garbage collection with something like this,

@Override
protected void finalize() {
  System.out.println("I will execute.");
}

public static void main(String args[]) {
  Test t = new Test();
  t = null;                     // <-- make it eligible for gc.
  System.gc();                  // <-- request gc.
  System.runFinalization();     // <-- run finalization(s).
  System.out.println("Exit");   // <-- exit.
}

Depending on your JVM, you might find the order of output swaps if you comment out System.runFinalization(); -

public static void main(String args[]) {
  Test t = new Test();
  t = null;                     // <-- make it eligible for gc.
  System.gc();                  // <-- request gc.
  // System.runFinalization();  // <-- run finalization(s).
  System.out.println("Exit");   // <-- exit.
}
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
0

Before removing an object from memory Garbage collection thread invokes finalize () method of that object and gives an opportunity to perform any sort of cleanup operations.

Generally an object becomes eligible for garbage collection in Java on following cases:

  1. All references of that object explicitly set to null e.g. object = null.
  2. Object is created inside a block and reference goes out scope once control exit that block.
  3. Parent object set to null, if an object holds reference of another object and when you set container object's reference null, child or contained object automatically becomes eligible for garbage collection.
  4. If an object has only live references via WeakHashMap it will be eligible for garbage collection.

    public Test(){ System.out.println("Object created"); } protected void finalize(){ System.out.println("Will i execute?"); } public static void main(String args[]){ Test test = new Test(); test = null; new Test(); System.gc(); }

SparkOn
  • 8,806
  • 4
  • 29
  • 34
0

finalize() of any particular class is called by jvm just before collecting the object of that class as a garbage.

Now next question is when an object of a class is collected as garbage? Answer is:

When there is no more objects reference to that object or simply no more object reference is pointing to that allocated memory space or an object has only live references via WeakHashMap it will be eligible for garbage collection. Read more here.

As an option we can use System.gc() or Runtime.gc() that will give a request to jvm to consider the garbage collection. But whether your request will be listened or ignored by jvm that depends upon following factors:

  1. Internal implementation of JVM & its Garbage Collection algorithm
  2. Java Heap size
  3. Free memory available in Heap
Shailesh Saxena
  • 3,472
  • 2
  • 18
  • 28