Java 为什么不打电话?

Java 为什么不打电话?,java,garbage-collection,Java,Garbage Collection,关于java中的垃圾收集器,我有几个问题 据我所知,当对象超出范围并且JVM即将收集垃圾时,就会调用finalize()。我认为finalize()方法是由垃圾收集器自动调用的,但在这种情况下它似乎不起作用。原因是什么?为什么我需要显式调用finalize()方法 问题2。此外,何时调用垃圾收集器?我知道gc是一个守护进程线程,由JVM根据剩余堆大小调用。这是否意味着JVM等待程序使用资源的阈值限制,然后通知gc清除垃圾对象 编辑:gc如何解析循环引用?它最终会被调用,或者根本不会被调用 基本上

关于java中的垃圾收集器,我有几个问题

据我所知,当对象超出范围并且JVM即将收集垃圾时,就会调用finalize()。我认为finalize()方法是由垃圾收集器自动调用的,但在这种情况下它似乎不起作用。原因是什么?为什么我需要显式调用finalize()方法

问题2。此外,何时调用垃圾收集器?我知道gc是一个守护进程线程,由JVM根据剩余堆大小调用。这是否意味着JVM等待程序使用资源的阈值限制,然后通知gc清除垃圾对象

编辑:gc如何解析循环引用?

它最终会被调用,或者根本不会被调用

基本上,GC会扫描堆中不可访问的所有内容,并在这些内容上运行终结器(之后需要再次证明它不可访问才能释放)

但是,GC可能需要一段时间(实际上是未定义的,实际上取决于程序行为)才能找到它,这就是为什么您不应该真正依赖它来处理关键数据的原因

编辑:对于循环引用,它区分使用finalize方法的对象和不使用finalize方法的对象

对于要释放(从主存删除)的对象,任何代码都可能无法访问该对象(包括仍需要运行的终结器)

当两个具有终结器的对象有资格运行终结器时,GC会任意选择一个对象并在其上运行终结器,然后可以运行另一个对象

请注意,终结器可以运行,而对象的字段可能已终结,也可能尚未终结。

finalize()方法在垃圾收集期间自动调用。方法强制调用垃圾收集器。但我们必须先摧毁这个物体。 例如:

q1)在垃圾收集对象时调用finalize方法,因此,如果没有执行GC,则可能不会调用终结器。您需要调用super simply来保留对象实现提供的行为

q2)执行GC的确切时间取决于许多因素,例如:您使用的JVM、调优参数、空闲堆的数量等。因此,它不仅取决于使用的堆阈值。您也可以要求通过System.GC()执行GC,但您无法保证是否以及何时实际执行。 您可以在

中找到有关如何配置GC的一些详细信息。方法finalize()有很多内容需要完成,坦率地说,这需要编写很多内容,但简而言之:

如果对象在其finalize方法(如果有的话)运行后仍然无法访问,则该对象处于finalize状态。已完成的对象正在等待解除分配。请注意,VM实现控制何时运行终结器。您几乎总是最好自己进行清理,而不是依赖终结器。使用终结器还可以留下关键资源,这些资源在不确定的时间内无法恢复

在您的情况下,它不打印的原因是您不知道终结器线程何时调用finalize()方法。发生的情况是,程序在打印任何内容之前终止。要检查它,请执行以下操作: 编辑主代码中的代码(注意:这并不保证你也不应该依赖它,但它确实会打印一些时间)


for(int i=0;iGC在JVM认为需要调用它时执行,尽管IIRC Oracle JVM实际上会使用System.gc()调用它。IIRC也不能保证调用它。对于您的示例,您如何测试是否/何时调用它?不要使用finalize()它绝不等于一个C++析构函数。@ DWB我同意,但是在java中实现一个类似于析构函数的行为的方法是:无bug的资源清理。用于无缺陷资源清理的块。@DWB在某些情况下不是解决方案,例如您在屏幕上绘制了图像的对象中使用了paint方法,但现在它超出了范围,但图像仍然显示在屏幕上。您需要一个析构函数来清理屏幕上的图像。不是吗?System.gc()无法强制JVM运行垃圾收集器。它只通知JVM对象已打开进行收集。
System.gc()
不强制垃圾收集。请注意,垃圾收集是必需的,但JVM仅在希望运行垃圾收集时才会运行垃圾收集。这里的要点是,必须将对象设置为“null”或销毁,才能看到正在调用的finalize方法(如上面的代码所示)。否则每当垃圾收集发生时,JVM将调用finalize方法。即使
System.gc()
触发垃圾收集,也无法保证看到
finalize()
方法的效果(实际上,在本例中不太可能),因为在垃圾收集器将对象排入队列后,终结会异步进行,这里,JVM会在垃圾收集后立即退出。这也取决于JVM的设置方式。-XX:DisableExplicitGC JVM标志可用于配置显式System.gc()是否有任何效果。因此,您的意思是添加finalize()方法不能确保无错误的清理?例如,在这种情况下,如果有一个文件对象打开,我想在保存该文件对象的对象死亡之前清理它,那么finalize()方法没有任何用处,除非显式调用。@prap19是的,这就是为什么
close()
依赖的不仅仅是
finalize()
close()对象的情况下的函数?这就是你的意思吗?就文件而言,这只是一个例子。我关心的是对象中类似析构函数的行为JAVA@prap19我的意思是
close()
可关闭的
接口,很多时候finalize是完全无用的,或者有一个显式处理资源的解决方案Java 7有可能使用自动资源管理(带
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);
    }
}
     public class Sample 
{
    public Sample()
    {
        System.out.println("Object created");
    }
    @Override
    public void finalize()
    {
        System.out.println("Object Destroyed");
    }
    public static void main(String args[])
    {
        Sample x=new Sample();
        Sample y=new Sample();

        x=null;
        y=null;

        System.gc();
    }
}
for(int i =0;i<1000000;i++)
    {
        MultipleConstruct construct = new MultipleConstruct(3);
        construct = null;
    }