【问题标题】:Is object eligible for garbage collection after "obj = null"?在“obj = null”之后对象是否有资格进行垃圾回收?
【发布时间】:2013-03-19 06:13:15
【问题描述】:

我知道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");
    }
}

【问题讨论】:

  • 也不能保证finalize 会被调用
  • 不符合条件,因为您的 obj 引用为空,但在仍然可以访问的存在的列表中。
  • 虽然答案是“否”(假设变量总是强根),但这是一个有趣的观点。在 .NET/C# 中,SomeClass 对象可能被垃圾回收,因为list 本身没有被使用 [稍后]。这是一个实际的 .NET 问题,在长时间运行的方法中存在计时器回调。问题是:在Java中,可见堆栈上的每个变量总是保证是强根吗?

标签: java garbage-collection


【解决方案1】:

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

但是,一旦此方法返回 list 超出范围,那么 obj 就会有资格进行垃圾回收(list 也是如此)。

仅将引用 obj 设置为 null 本身并不会使引用的对象符合垃圾回收的条件。只有在可见对象图中没有对对象的引用时,该对象才符合条件。

【讨论】:

  • 当你将obj设置为null时,它在列表中是不是也变成了null? List 只是指向之前 obj 所在的位置。
  • 没有。 Java 使用引用,而不是指针。当您将项目添加到列表时,它会获取引用的副本并存储它。更改原始引用不会更改复制的引用,因此 SomeClass 实例仍然可以访问。
  • 同意,上述情况不会被垃圾回收。
【解决方案2】:

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

只有那些连一个引用都没有的对象会被垃圾回收。 (循环连接除外)

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

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

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

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

【讨论】:

  • 哪里有保证list是强根? (我确定它在某些规范中 :-) list 对象在调用System.gc 之后 未使用,因此从技术上讲,它不是“需要”之后,因此可以(这是我不确定保证的地方)可能有资格进行垃圾收集吗?或者调用框架的存在是否要求所有局部变量在所有条件下都是强根?即使是 JIT 了?
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

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

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

    编辑:

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

    不,因为对象仍在 ArrayList 中。

    【讨论】:

    • 问题是关于对象是否有资格进行垃圾回收。
    • 是的,他是。他还指出,他知道它不会强制运行垃圾收集。您尚未回答以下问题:“对象obj 是否有资格进行垃圾回收?”
    【解决方案5】:

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

    【讨论】:

    • 答案是否定的。尽快阅读“Head First Core Java”。
    猜你喜欢
    • 2013-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    • 1970-01-01
    • 2018-07-19
    相关资源
    最近更新 更多