Вызывает ли JVM / GC `finalize ()` при выходе из программы / потока?

PS: Я знаю, как правильно выполнять очистку, вне зависимости от finalize () .

Не гарантирует ли Java, что при выходе из программы будет произведена правильная сборка мусора?

Например. скажем, я сохранил некоторые данные в кеше вместо частой их сериализации, я также реализовал finalize () в надежде, что если по какой-либо причине (кроме сбоя) моя программа завершится корректно, то кеш будет быть записанным в DB / file / some-storage моим кодом в методе finalize (). Но согласно следующему небольшому эксперименту кажется, что JVM не очищает память «изящно», а просто завершает работу.

Спецификация Java (см. Выход из программы) НИЧЕГО не говорит о том, как обрабатывается память / gc при выходе. Или мне следовало искать другой раздел спецификации?

Возьмем следующий пример (вывод в конце) с использованием 64-битной версии 1.6.0.27 в 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);
 */

Варианты:

  • Если я раскомментирую любой из них System.gc () , то не вызывается finalize () .
  • Если я раскомментирую оба System.gc () , то finalize () вызывается дважды.
  • Независимо от того, вызывается ли System.exit () или нет, не влияет на то, вызывается ли finalize () или нет.

12
задан Kashyap 24 October 2011 в 19:06
поделиться