Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does JVM/GC call `finalize()` on program/thread exit?

Tags:

java

PS: I do know how to cleanup correctly, without depending on finalize().

Does Java not guarantee that on program exit, proper garbage collection will be done?

E.g. lets say I've kept some data in cache instead of serializing it frequently, I also implemented finalize() with the hope that if due to whatever reason (except crash) my program exits gracefully, then the cache would be written to DB/file/some-storage by my code in finalize() method. But according to following little experiment it seems like JVM doesn't cleanup memory "gracefully", it just exits.

Java spec (see program exit) says NOTHING abt how memory / gc is handled on exit. Or should I have been looking at a different section of the spec?

Take the following example (output at the end) using 1.6.0.27 64 bits, on Windows 7

public class Main {

        // just so GC might feel there is something to free..
    private int[] intarr = new int[10000];

    public static void main(String[] args) {
        System.out.println("entry");
        Main m = new Main();
        m.foo();
        m = new Main();
        // System.gc();
        m.foo();
        m = null;
        // System.gc();
        System.out.println("before System.exit(0);");
        System.exit(0);
    }

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

    public void foo() { System.out.println("foo()"); }
}

/*
 * Prints:
 * entry 
 * foo() 
 * foo() 
 * before System.exit(0);
 */

Variations:

  • If I uncomment any one System.gc() then no finalize() is called.
  • If I uncomment both System.gc() then finalize() is called twice.
  • Whether System.exit() is called or not has no effect on whether finalize() is called or not.
like image 278
Kashyap Avatar asked Oct 24 '11 19:10

Kashyap


2 Answers

No, Java does not guarantee that on program exit the GC will trigger. If you want an operation to peform on exit use Runtime.addShutdownHook method. Read this Sun article on what the SPEC says.

The specification for the Java platform makes very few promises about how garbage collection actually works. Here is what the Java Virtual Machine Specification (JVMS) has to say about memory management.

The heap is created on virtual machine start-up. Heap storage for objects is reclaimed by an automatic storage management system (known as a garbage collector); objects are never explicitly deallocated. The Java virtual machine assumes no particular type of automatic storage management system, and the storage management technique may be chosen according to the implementor's system requirements.1 While it can seem confusing, the fact that the garbage collection model is not rigidly defined is actually important and useful-a rigidly defined garbage collection model might be impossible to implement on all platforms. Similarly, it might preclude useful optimizations and hurt the performance of the platform in the long term.

Although there is no one place that contains a full definition of required garbage collector behavior, much of the GC model is implicitly specified through a number of sections in the Java Language Specification and JVMS. While there are no guarantees about the exact process followed, all compliant virtual machines share the basic object lifecycle described in this chapter.

like image 198
Amir Afghani Avatar answered Oct 15 '22 02:10

Amir Afghani


See Runtime.runFinalizersOnExit(). Note that it is deprecated, and note the rest of the commentary. I think you can legitimately infer from all that that it is off by default, but you should also note that it can be turned on.

like image 45
user207421 Avatar answered Oct 15 '22 01:10

user207421