Method finalize in Java

By calling the finalize() method (which inherits from Java.lang.Object), the JVM implements functionality similar to the C++ destructors used to clear memory before returning control to the operating system. This method is called when the object is destroyed by the garbage collector and by overriding finalize(), you can program the actions necessary for the correct deletion of the class instance - for example, closing network connections, database connections, unlocking files, etc.

After executing this method, the object must be re-collected by the garbage collector (and this is considered a serious problem with the finalize() method as it prevents the garbage collector from freeing memory). This method is not guaranteed to be called because the application can be terminated before garbage collection starts.

The object will not necessarily be immediately available for assembly - the finalize() method can store a reference to the object somewhere. Such a situation is called "reviving" an object and is considered an anti-pattern. The main problem with this trick is that you can only "revive" an object once.

Example:

public class MainClass {

    public static void main(String args[]) {
        TestClass a = new TestClass();
        a.a();
        a = null;
        a = new TestClass();
        a.a();
        System.out.println("!!! done");
    }
}
public class TestClass {

    public void a() {
        System.out.println("!!! a() called");
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println("!!! finalize() called");
        super.finalize();
    }
}

Since in this case the garbage collector may not be called (due to the simplicity of the application), the result of program execution is likely to be the following:

!!! a() called
!!! a() called
!!! done

Now let's complicate the program a little by adding a forced call to Garbage Collector:

public class MainClass {

    public static void main(String args[]) {
        TestClass a = new TestClass();
        a.a();
        a = null;
        System.gc(); // Forcibly call the garbage collector
        a = new TestClass();
        a.a();
        System.out.println("!!! done");
    }

}

As mentioned earlier, the Garbage Collector can run at different times, so the execution result may vary from run to run:

Option a:

!!! a() called
!!! a() called
!!! done
!!! finalize() called

Option b:

!!! a() called
!!! a() called
!!! finalize() called
!!! done


Read also:


Comments

Popular posts from this blog

Methods for reading XML in Java

XML, well-formed XML and valid XML

ArrayList and LinkedList in Java, memory usage and speed