java - 面试题: Objects eligible for garbage collection

标签 java garbage-collection

给出以下代码:

class A {
    Boolean b;
    A easyMethod(A a){
        a = null;
        return a;
    }
    public static void main(String [] args){
        A a1 = new A();
        A a2 = new A();
        A a3 = new A();
        a3 = a1.easyMethod(a2);
        a1 = null;
        // Some other code 
    }
}

问题是在 //Some other code 之前有多少对象可以进行垃圾回收。

那么正确答案是(至少那是面试官的答案): 2 - boolean 值 b 因为它是一个包装器和 a1

你能解释一下为什么 a2a3 没有被垃圾收集吗?

稍后编辑:

  • 好的,我想我现在明白了。一开始有点困惑,但现在我确定面试官错了。我最初的错误是,一开始我并没有考虑到 Java 只是按值传递,所以不可能从以“a2”作为参数的函数内部使 a2 为空,因为 a2 实际上是 a2 的副本。
  • 带有 boolean b的部分确实很明显。

感谢您的回答,之后我会发送一些面试反馈:)。

最佳答案

假设 go 应该是 easyMethod 它像这样工作

class A {
    Boolean b;
    A easyMethod(A a){
        a = null; // the reference to a2 was passed in, but is set to null
                  // a2 is not set to null - this copy of a reference is!
        return a; // null is returned
    }
    public static void main(String [] args){
        A a1 = new A(); // 1 obj
        A a2 = new A(); // 2 obj
        A a3 = new A(); // 3 obj
        a3 = a1.go(a2); // a3 set to null and flagged for GC - see above for why
        a1 = null; // so far, a1 and a3 have been set to null and flagged
        // Some other code 
    }
}

有两个对象可以进行垃圾回收(a1 和 a3)。 b 不是因为它只是对 null 的引用。从来没有Boolean

为了解决 //Some other code 可能是什么的愚蠢微妙之处,我将问题改写为以下内容:

预测并解释以下输出:

class A {
    int i;
    A(int i) { this.i = i; }
    public String toString() { return ""+i; }
    A go(A a){
        a = null; // the reference to a2 was passed in, but is set to null
                  // a2 is not set to null - this copy of a reference is!
        return a; // null is returned
    }
    public static void main(String [] args){
        A a1 = new A(1); // 1 obj
        A a2 = new A(2); // 2 obj
        A a3 = new A(3); // 3 obj
        a3 = a1.go(a2); // a3 set to null and flagged for GC - see above for why
        a1 = null; // so far, a1 and a3 have been set to null and flagged

        test(a1);
        test(a2);
        test(a3);

    }
    static void test(A a) {
        try { System.out.println(a); } 
        catch(Exception e) { System.out.println((String)null); }
    }
}

然后输出:

c:\files\j>javac A.java

c:\files\j>java A
null
2
null

后续的是,此时,a1 和 a3 符合 GC 条件,而 a2 则没有。

这个问题的教训是“将对象引用传递给方法并将该引用设置为 null 不会导致原始引用为 null”。这就是面试官试图测试的知识。

关于java - 面试题: Objects eligible for garbage collection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3299604/

相关文章:

ruby - `RUBY_GC_OLDMALLOC_LIMIT` 和 `RUBY_GC_MALLOC_LIMIT` 和有什么区别?

java - 当老一代/年轻一代有很多空间时,我经常看到主要的 gc

javascript - window.location 重定向后是否调用垃圾收集器?

java - 致命异常。使用Retrofit2-beta3无法使用retrofit2从apiUrl检索数据

Java IOException 无限循环

java - 测量 GC 暂停时间的最佳方法是什么?

garbage-collection - 防止 CLR 中早期垃圾回收的最佳方法

java - 推荐的规则集

java - SockJsClient 抛出 ClassCastException

java - Json反序列化器可以在java中的不同类中工作