pra*_*p19 10 java garbage-collection
我有几个关于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);
}
}
Run Code Online (Sandbox Code Playgroud)
Q2.另外,什么时候调用垃圾收集器?我理解gc是一个守护程序线程,由JVM根据剩余的堆大小调用.这是否意味着,JVM等待程序使用资源的阈值限制,然后通知gc扫描垃圾对象.
编辑: gc如何解决循环引用?
finalize()方法有很多东西,坦率地写了很多,但简而言之:
如果一个对象在其finalize方法(如果有的话)运行后仍然无法访问,则它处于最终状态.最终的对象正在等待释放.请注意,VM实现控制何时运行终结器.你几乎总是更好地做自己的清理,而不是依靠终结器.使用终结器还可以留下在不确定的时间内无法恢复的关键资源.
在您的情况下,它不打印的原因是您不知道终结器线程何时将调用finalize()方法.发生的事情是该程序在任何可以打印之前终止.要检查一下:编辑主代码中的代码(注意:这不是保证,也不应该依赖它,但它仍会打印一段时间)
for(int i =0;i<1000000;i++)
{
MultipleConstruct construct = new MultipleConstruct(3);
construct = null;
}
Run Code Online (Sandbox Code Playgroud)
使用finalize()有很多缺点,从在对象构造中花费更多时间到内存泄漏和内存不足的可能性.如果你强烈引用finalize()中的同一个对象,那么它永远不会被第二次调用,从而可以使系统处于不希望的状态等等...你应该使用finalize()的唯一地方是作为安全网处理任何资源,如InputStream使用它来关闭(这也没有保证,当你的程序还活着时它会运行).另一个使用它的地方是使用垃圾收集器无法控制的本机.
欲了解更多信息,请访
q1)在垃圾回收对象时调用finalize方法,因此,如果没有执行GC,则可能不会调用您的finalizer。您只需调用super即可保留Object实现提供的行为。
q2)执行GC的确切时间取决于许多因素,例如:您使用的JVM,调整参数,可用堆的数量等。因此,它不仅依赖于已使用的堆阈值。您也可以要求通过System.gc()执行GC,但是不能保证是否以及何时实际执行GC。您可以在http://java.sun.com/performance/reference/whitepapers/tuning.html中找到有关如何配置GC的一些详细信息。
| 归档时间: |
|
| 查看次数: |
12401 次 |
| 最近记录: |