3

我知道System.gc()不保证会导致GC,但是理论上,在下面的代码中,对象obj是否有资格进行垃圾回收?

public class Demo {

    public static void main(String[] args) throws Exception {
        SomeClass obj = new SomeClass();
        ArrayList list = new ArrayList();
        list.add(obj);
        obj = null;
        System.gc();
    }

}

class SomeClass {
    protected void finalize() {
        System.out.println("Called");
    }
}
4

5 回答 5

9

在您调用您创建System.gc()SomeClass实例时,它符合垃圾收集条件,因为它仍然被list对象引用,即它仍然是可访问的。

但是,一旦此方法返回list超出范围,soobj就会有资格进行垃圾收集(就像 will 一样list)。

简单地将引用设置obj为 null 本身并不能使引用的对象符合垃圾回收的条件。一个对象只有在可见对象图中没有对其的引用时才符合条件。

于 2013-03-19T06:17:26.830 回答
4

对象 obj 是否有资格进行垃圾收集?

只有那些甚至没有一个参考可以到达它们的对象才会被垃圾收集。(循环连通性除外)

在您的代码中,有两个引用指向new SomeClass();

  1. 对象
  2. 列表的第零个索引

你把obj = null, 即它不再指向那个对象了。但是,列表中仍然存在另一个可用于访问该对象的引用。

因此,该对象仅在main返回时才有资格进行 GC。即,finalize即使它被调用,你也看不到方法的输出。(不确定JVM是否仍然调用它)

于 2013-03-19T06:25:54.787 回答
3

不,因为该对象实际上存在于列表中。

于 2013-03-19T06:18:07.720 回答
1

作为 Java 程序员,你不能在 Java 中强制垃圾回收;只有当 JVM 认为它需要基于 Java 堆大小的垃圾收集时才会触发

当 Java 程序启动时,Java 虚拟机从操作系统中获取一些内存。Java 虚拟机或 JVM 使用此内存来满足其所有需求,并且此内存的一部分称为 java 堆内存。

Java中的堆一般位于地址空间的底部并向上移动。每当我们使用 new 运算符或任何其他方式创建对象时,都会从堆中为对象分配内存,当对象死亡或垃圾收集时,内存会回到 Java 中的堆空间

编辑 :

对象 obj 是否有资格进行垃圾收集?

不,因为对象仍在 ArrayList 中。

于 2013-03-19T06:18:32.553 回答
-2

同意,只要它在列表中,它就不会被垃圾收集。

于 2013-03-19T06:14:03.230 回答