如何在java中销毁对象?

如何在java中销毁对象?,java,garbage-collection,finalize,Java,Garbage Collection,Finalize,我在一次采访中遇到了这个问题,有以下几种选择: 如何在java中销毁对象 答案应该是e 如果e不在那里呢?那么? 显然c不是答案。a和b将对整个应用程序执行gc(问题需要一个对象)。 我认为这是d,因为finalize()是在gc之前调用的(但是否有必要在finalize之后调用gc?),或者我错了?我必须在那里回答这个问题吗 答案E是正确答案。如果E不在那里,您将很快耗尽内存(或)没有正确答案 对象应该不可访问,才能符合GC的条件。JVM将进行多次扫描,并将对象从一代移动到另一代,以确定GC的

我在一次采访中遇到了这个问题,有以下几种选择:

如何在java中销毁对象

  • 答案应该是e

  • 如果e不在那里呢?那么? 显然c不是答案。a和b将对整个应用程序执行gc(问题需要一个对象)。 我认为这是d,因为finalize()是在gc之前调用的(但是否有必要在finalize之后调用gc?),或者我错了?我必须在那里回答这个问题吗


  • 答案E是正确答案。如果E不在那里,您将很快耗尽内存(或)没有正确答案

    对象应该不可访问,才能符合GC的条件。JVM将进行多次扫描,并将对象从一代移动到另一代,以确定GC的合格性,并在无法访问对象时释放内存。

    Short Response-E 答案是
    E
    ,因为其余的显然是错的,但是

    答案很长——没那么简单;这取决于。。。 简单的事实是,除非内存压力非常高,否则垃圾收集器可能永远不会决定对每个可行的候选对象进行垃圾收集。还有一个事实,Java和其他任何语言一样容易受到内存泄漏的影响,它们更难引起,因此当你真的引起内存泄漏时,就更难发现了

    下面的文章详细介绍了内存管理的工作原理和不工作原理,以及什么占用了哪些内存。及


    如果您阅读了这些链接,我想您会明白Java中的内存管理并不像一个选择题那么简单。

    为了澄清为什么其他答案不起作用:

  • System.gc()
    (以及执行完全相同操作的
    Runtime.getRuntime().gc()
    )提示您希望销毁内容。模糊地。如果JVM认为没有必要运行GC循环,它可以随意忽略运行GC循环的请求。另外,除非你已经清空了所有对该对象的可访问引用,否则GC无论如何都不会触及它。所以A和B都被取消资格

  • Runtime.getRuntime.gc()
    语法错误
    getRuntime
    是一个函数,而不是一个变量;你需要在它后面加括号才能调用它。所以B是双重取消资格

  • 对象
    没有
    删除
    方法。所以C被取消资格

  • 虽然
    Object
    有一个
    finalize
    方法,但它不会破坏任何东西只有垃圾收集器才能真正删除对象。(在许多情况下,从技术上讲,他们甚至懒得这么做;他们只是在执行其他操作时不复制它,所以它会被甩在后面。)finalize所做的就是在JVM丢弃对象之前给对象一个清理的机会。此外,您永远不应该直接调用
    finalize
    。(由于
    finalize
    受到保护,JVM无论如何都不会让您在任意对象上调用它。)因此D被取消资格

  • 除此之外,
    object.doanythingatallevencommitside()
    还要求运行的代码引用
    object
    。单凭这一点,它就“活着”,因此没有资格进行垃圾收集。所以C和D被双重取消资格


  • 代码如下:

    public static void main(String argso[]) {
    int big_array[] = new int[100000];
    
    // Do some computations with big_array and get a result. 
    int result = compute(big_array);
    
    // We no longer need big_array. It will get garbage collected when there
    // are no more references to it. Since big_array is a local variable,
    // it refers to the array until this method returns. But this method
    // doesn't return. So we've got to explicitly get rid of the reference
    // ourselves, so the garbage collector knows it can reclaim the array. 
    big_array = null;
    
    // Loop forever, handling the user's input
    for(;;) handle_input(result);
    }
    

    设置为空。然后就没有引用了,对象就可以进行垃圾收集了。GC将自动从堆中删除对象。

    在java中,没有明确的垃圾收集方法。JVM本身在后台运行一些线程,检查没有任何引用的对象,这意味着我们访问对象的所有方式都丢失了。另一方面,如果一个对象超出了我们创建该对象的程序终止或结束的范围,那么它也有资格进行垃圾收集。 最后的方法与C++中的析构函数相同。finalize方法实际上是在JVM清除对象内存之前调用的。是否在程序中定义finalize方法取决于您。但是,如果对象的垃圾收集是在程序终止后完成的,那么JVM将不会调用您在程序中定义的finalize方法。 您可能会问finalize方法的用途是什么? 例如,让我们考虑创建一个需要一些对象的对象。
    流到外部文件,您为此对象显式定义了一个finalize方法,该方法检查流是否打开到文件,如果没有打开,则关闭流。假设,在编写了几行代码之后,您丢失了对对象的引用。那么它就有资格进行垃圾收集。当JVM即将释放对象的空间时,JVM只需检查您是否定义了finalize方法并调用该方法,这样就不会有打开流的风险。finalize方法使程序无风险且更健壮。

    如果没有e,请自己编写。其他选项都不是答案,Java不允许您破坏对象。任何不可到达的对象可能(也可能不)在任何特定的时间点进行GCD。这是正确的。没有正确的答案,但是E.java会变成C++。这仍然不是100%正确的,对象可以生存整个应用程序的时间,即使它们是“不可到达”的,它们与内存的压力没有太大关系。JVM不试图保持最大可用空间,这将是一种资源浪费。应该有一种编程语言,在这种语言中,gems应该是legal statements->object.doanythingatallevencommitsucide()
    public static void main(String argso[]) {
    int big_array[] = new int[100000];
    
    // Do some computations with big_array and get a result. 
    int result = compute(big_array);
    
    // We no longer need big_array. It will get garbage collected when there
    // are no more references to it. Since big_array is a local variable,
    // it refers to the array until this method returns. But this method
    // doesn't return. So we've got to explicitly get rid of the reference
    // ourselves, so the garbage collector knows it can reclaim the array. 
    big_array = null;
    
    // Loop forever, handling the user's input
    for(;;) handle_input(result);
    }