51

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

如何在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(问题需要一个对象)。我认为它是 d 因为 finalize() 在 gc 之前被调用(但是在 finalize gc 被调用之后是否有必要?)或者我错了?e 必须在那里回答这个问题吗?

4

6 回答 6

66

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

对象应该是不可访问的,才有资格进行 GC。JVM 会进行多次扫描并将对象从一代移动到另一代,以确定 GC 的资格,并在对象不可达时释放内存。

于 2012-11-03T03:53:53.473 回答
39

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

  1. System.gc()(连同Runtime.getRuntime().gc(),它做完全相同的事情)暗示你想要破坏的东西。依稀。如果 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 被双重取消资格。

于 2012-11-03T04:16:59.683 回答
19

简答 - E

给出的答案是E其余的显然是错误的,但是..

长答案 - 没那么简单;这取决于 ...

简单的事实是,垃圾收集器可能永远不会决定对每个可行的回收对象进行垃圾收集,除非内存压力非常高。还有一个事实是,Java 与任何其他语言一样容易受到内存泄漏的影响,它们只是更难导致,因此当你确实导致它们时更难找到!

下面的文章有很多关于内存管理如何工作和不工作以及什么被什么占用的详细信息。世代垃圾收集器如何工作感谢内存(了解 JVM 如何在 Windows 和 Linux 上使用本机内存)

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

于 2012-11-03T04:09:54.663 回答
10

设置为空。然后不再有引用,该对象将有资格进行垃圾收集。GC 会自动从堆中删除对象。

于 2016-10-30T00:26:39.740 回答
4

这是代码:

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);
}
于 2016-04-28T12:33:23.803 回答
0

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

于 2017-03-19T15:38:57.260 回答