PS:我确实知道如何正确清理,而不依赖于 finalize()
。
Java不能保证在程序退出时,会进行适当的垃圾收集吗?
例如。假设我已经在缓存中保留了一些数据而不是频繁地序列化,我也实现了 finalize()
希望如果由于任何原因(崩溃除外)我的程序正常退出,那么缓存将通过我的代码在finalize()方法中写入DB / file / some-storage。但根据以下小实验,似乎JVM不会“优雅地”清理内存,它只是退出。
Java规范 (参见程序退出)说明没有在退出时如何处理内存/ gc。或者我应该查看规范的不同部分?
在Windows 7上使用1.6.0.27 64位进行以下示例(最后输出)
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()
是否被召唤。