如何在java中销毁一个对象?

时间:2012-11-03 03:52:25

标签: java garbage-collection finalize

我在接受以下选项的采访中遇到了这个问题:

  

如何在java中销毁对象?

a. System.gc();  
b. Runtime.getRuntime.gc();  
c. object.delete();  
d. object.finalize();  
e. Java performs gc by itself, no need to do it manually.
  1. 答案应该是e?

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

6 个答案:

答案 0 :(得分:50)

答案E是正确答案。如果E不在那里,你很快就会用尽内存(或)没有正确答案。

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

答案 1 :(得分:28)

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

  1. System.gc()(与Runtime.getRuntime().gc()一起完成同样的事情)提示您希望销毁的内容。依稀。如果JVM没有看到需要,那么JVM可以自由地忽略运行GC循环的请求。另外,除非您已经清除了对象的所有可访问引用,否则GC无论如何都不会触及它。所以A和B都被取消资格。

  2. Runtime.getRuntime.gc()语法错误。 getRuntime是一个函数,而不是一个变量;你需要用括号来调用它。所以B被双重取消资格。

  3. Object没有delete方法。所以C被取消资格。

  4. 虽然Object 具有finalize方法,但它不会销毁任何内容。 只有垃圾收集器才能真正删除一个对象。(在很多情况下,他们在技术上甚至都不愿意 ;他们只是在他们没有复制时做其他人,所以它落后了。)所有finalize做的是让一个对象有机会在之前清理 JVM丢弃它。更重要的是,你永远不应该直接打电话给finalize。 (由于finalize受到保护,JVM不会让你在任意对象上调用它。)所以D被取消资格。

  5. 除此之外,object.doAnythingAtAllEvenCommitSuicide()要求正在运行的代码引用object。仅这一点使它“活着”,因此没有资格进行垃圾收集。所以C和D被双重取消资格。

答案 2 :(得分:16)

简答 - E

答案是E,因为其余的都是明显错误的,但是......

答案很长 - 不是那么简单;这取决于......

简单的事实是,垃圾收集器可能永远不会决定对每个对象进行垃圾收集,这是一个可行的收集候选对象,除非内存压力非常高。然后事实上,Java和其他任何语言一样容易受到内存泄漏的影响,它们更难以引起,因此当你造成它们时更难找到它们!

以下文章有许多关于内存管理如何工作和不起作用的详细信息,以及由什么引起的内容。 How generational Garbage Collectors workThanks for the Memory ( Understanding How the JVM uses Native Memory on Windows and Linux )

如果您阅读了这些链接,我想您会认为Java中的内存管理并不像多项选择问题那么简单。

答案 3 :(得分:6)

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

答案 4 :(得分:3)

以下是代码:

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);
}

答案 5 :(得分:0)

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