When is the finalize() method called in Java?

512,666

Solution 1

The finalize method is called when an object is about to get garbage collected. That can be at any time after it has become eligible for garbage collection.

Note that it's entirely possible that an object never gets garbage collected (and thus finalize is never called). This can happen when the object never becomes eligible for gc (because it's reachable through the entire lifetime of the JVM) or when no garbage collection actually runs between the time the object become eligible and the time the JVM stops running (this often occurs with simple test programs).

There are ways to tell the JVM to run finalize on objects that it wasn't called on yet, but using them isn't a good idea either (the guarantees of that method aren't very strong either).

If you rely on finalize for the correct operation of your application, then you're doing something wrong. finalize should only be used for cleanup of (usually non-Java) resources. And that's exactly because the JVM doesn't guarantee that finalize is ever called on any object.

Solution 2

protected void finalize() throws Throwable {}
  • every class inherits the finalize() method from java.lang.Object
  • the method is called by the garbage collector when it determines no more references to the object exist
  • the Object finalize method performs no actions but it may be overridden by any class
  • normally it should be overridden to clean-up non-Java resources ie closing a file
  • if overridding finalize() it is good programming practice to use a try-catch-finally statement and to always call super.finalize(). This is a safety measure to ensure you do not inadvertently miss closing a resource used by the objects calling class

    protected void finalize() throws Throwable {
         try {
             close();        // close open files
         } finally {
             super.finalize();
         }
     }
    
  • any exception thrown by finalize() during garbage collection halts the finalization but is otherwise ignored

  • finalize() is never run more than once on any object

quoted from: http://www.janeg.ca/scjp/gc/finalize.html

You could also check this article:

Solution 3

The Java finalize() method is not a destructor and should not be used to handle logic that your application depends on. The Java spec states there is no guarantee that the finalize method is called at all during the livetime of the application.

What you problably want is a combination of finally and a cleanup method, as in:

MyClass myObj;

try {
    myObj = new MyClass();

    // ...
} finally {
    if (null != myObj) {
        myObj.cleanup();
    }
}

This will correctly handle the situation when the MyClass() constructor throws an exception.

Solution 4

Check out Effective Java, 2nd edition page 27. Item 7: Avoid finalizers

Finalizers are unpredictable, often dangerous, and generally unnecessary. never do anything time-critical in a finalizer. never depend on a finalizer to update critical persistent state.

To terminate a resource, use try-finally instead:

// try-finally block guarantees execution of termination method
Foo foo = new Foo(...);
try {
    // Do what must be done with foo
    ...
} finally {
    foo.terminate(); // Explicit termination method
}

Solution 5

When is the finalize() method called in Java?

The finalize method will be called after the GC detects that the object is no longer reachable, and before it actually reclaims the memory used by the object.

  • If an object never becomes unreachable, finalize() will never be called on it.

  • If the GC doesn't run then finalize() may never be called. (Normally, the GC only runs when the JVM decides that there is likely to enough garbage to make it worthwhile.)

  • It may take more than one GC cycle before the GC determines that a specific object is unreachable. (Java GCs are typically "generational" collectors ...)

  • Once the GC detects an object is unreachable and finalizable, it is places on a finalization queue. Finalization typically occurs asynchronously with the normal GC.

(The JVM spec actually allows a JVM to never run finalizers ... provided that it doesn't reclaim the space used by the objects. A JVM that was implemented this way would be crippled / useless, but it this behavior is "allowed".)

The upshot is that it is unwise to rely on finalization to do things that have to be done in a definite time-frame. It is "best practice" not to use them at all. There should be a better (i.e. more reliable) way to do whatever it is you are trying to do in the finalize() method.

The only legitimate use for finalization is to clean up resources associated with objects that have been lost by application code. Even then, you should try to write the application code so that it doesn't lose the objects in the first place. (For example, use Java 7+ try-with-resources to ensure that close() is always called ...)


I created a test class which writes into a file when the finalize() method is called by overriding it. It is not executed. Can anybody tell me the reason why it is not executing?

It is hard to say, but there are a few possibilities:

  • The object is not garbage collected because it is still reachable.
  • The object is not garbage collected because the GC doesn't run before your test finishes.
  • The object is found by the GC and placed in the finalization queue by the GC, but finalization isn't completed before your test finishes.
Share:
512,666
Rajesh Kumar J
Author by

Rajesh Kumar J

I have a Bachelor's degree in CS. Likes programming.

Updated on July 08, 2022

Comments

  • Rajesh Kumar J
    Rajesh Kumar J almost 2 years

    I need to know when the finalize() method is called in the JVM. I created a test class which writes into a file when the finalize() method is called by overriding it. It is not executed. Can anybody tell me the reason why it is not executing?