PS:我确实知道如何正确清理,而不依赖于finalize().
Java不保证在程序退出时,会进行适当的垃圾收集吗?
例如,假设我已经将一些数据保存在缓存中而不是频繁地将其序列化,我还finalize()希望如果由于任何原因(除了崩溃)我的程序正常退出,那么缓存将被写入DB/file/some - 我的代码在finalize()方法中存储.但根据以下小实验,似乎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);
*/
Run Code Online (Sandbox Code Playgroud)
变化:
System.gc()则不会finalize()被调用.System.gc()则finalize()调用两次.System.exit()被调用对是否finalize()被调用没有影响.Ami*_*ani 10
不,Java不保证在程序退出时GC会触发.如果要在退出使用Runtime.addShutdownHook方法上执行操作.阅读这在SPEC说什么孙文章.
Java平台的规范很少有关于垃圾收集实际工作方式的承诺.以下是Java虚拟机规范(JVMS)对内存管理的看法.
堆是在虚拟机启动时创建的.对象的堆存储由自动存储管理系统(称为垃圾收集器)回收; 对象永远不会被显式释放.Java虚拟机假定没有特定类型的自动存储管理系统,并且可以根据实现者的系统要求选择存储管理技术.1虽然看起来很混乱但是垃圾收集模型没有严格定义这一事实实际上很重要并且有用 - 在所有平台上都可能无法实现严格定义的垃圾收集模型.同样,它可能会排除有用的优化并长期损害平台的性能.
虽然没有一个地方包含所需垃圾收集器行为的完整定义,但是大部分GC模型是通过Java语言规范和JVMS中的许多部分隐式指定的.虽然无法保证所遵循的确切流程,但所有兼容的虚拟机都共享本章所述的基本对象生命周期.
| 归档时间: |
|
| 查看次数: |
5584 次 |
| 最近记录: |