PS: Я знаю, как правильно очищать, не зависимо от finalize()
.
Не гарантирует ли Java, что при выходе из программы будет выполнена сборка мусора?
например. скажем, я сохранил некоторые данные в кеше, а не сериализуя его часто, я также реализовал finalize()
с надеждой, что если по какой-либо причине (кроме краха) моя программа выйдет изящно, тогда кеш будет записан в DB/file/some-storage моим кодом в методе finalize(). Но в соответствии с следующим небольшим экспериментом кажется, что JVM не очищает память "изящно", она просто выходит.
Спецификация Java (см. выход программы) говорит НИЧЕГО, как память /gc обрабатывается при выходе. Или я должен был смотреть на другой раздел спецификации?
Возьмем следующий пример (вывод в конце) с использованием 1.6.0.27 64 бит в 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()
или нет.