我有几个关于java中的垃圾收集器的问题。
Q1.据我了解,当对象超出范围并且 JVM 即将收集垃圾时,finalize() 就会被调用。我认为 Finalize() 方法是由垃圾收集器自动调用的,但在这种情况下它似乎不起作用。解释是什么?为什么需要显式调用 Finalize() 方法?
public class MultipleConstruct {
int x,y;
public MultipleConstruct(int x)
{
this.x= x;
y=5;
System.out.println("ONE");
}
@Override
protected void finalize() throws Throwable {
// TODO Auto-generated method stub
super.finalize();
System.out.println("FINALIZED");
}
public static void main(String[] args) throws Throwable {
MultipleConstruct construct = new MultipleConstruct(3);
}
}
Q2。另外,什么时候调用垃圾收集器?我知道 gc 是一个守护线程,由 JVM 根据剩余的堆大小调用。这是否意味着,JVM 等待程序使用资源阈值限制,然后通知 gc 清理垃圾对象。
EDIT:gc如何解决循环引用?
Finalize() 方法有很多东西要写,坦率地说有很多东西要写,但简而言之:
如果对象在运行其 Finalize 方法(如果有)后仍然无法访问,则该对象处于 Finalized 状态。最终确定的对象正在等待释放。请注意,VM 实现控制终结器的运行时间。自己进行清理几乎总是比依赖终结器更好。使用终结器还可能留下在不确定的时间内无法恢复的关键资源。
在您的情况下,它不打印的原因是您不知道终结器线程何时调用 Finalize() 方法。发生的情况是程序在打印任何内容之前就终止了。要检查它:
编辑主代码中的代码(注意:这不能保证也不应该依赖它,但它仍然会打印一些时间)
for(int i =0;i<1000000;i++)
{
MultipleConstruct construct = new MultipleConstruct(3);
construct = null;
}
使用 Finalize() 有很多缺点,从花费更多时间来构造对象到可能出现内存泄漏和内存不足。如果您在 Finalize() 中强烈引用同一个对象,那么它永远不会被第二次调用,因此可能会使系统处于不期望的状态等等......
唯一应该使用 Finalize() 的地方是作为安全网来处理任何资源,例如 InputStream 使用它来关闭(同样不能保证当您的程序仍然存在时它将运行)。另一个使用它的地方是在使用垃圾收集器无法控制的本机时。
欲了解更多信息,请访问:
http://jatinpuri.com/?p=106 http://jatinpuri.com/?p=106
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)