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 ()
или нет.