-1

鉴于:

interface Animal {
    void makeNoise();
}

class Horse implements Animal {
    Long weight = 1200L;

    public void makeNoise() {
        System.out.println("whinny");
    }
}

public class Icelandic extends Horse {
    public void makeNoise() {
        System.out.println("vinny");
    }

    public static void main(String[] args) {
        Icelandic i1 = new Icelandic();
        Icelandic i2 = new Icelandic();
        Icelandic i3 = new Icelandic();
        i3 = i1;
        i1 = i2;
        i2 = null;
        i3 = i1;
        System.out.println("end of program");
    }
}

在最后一条语句中有多少对象符合垃圾收集器的条件(即:在哪里打印程序结束)?答案是 4 但我不明白它们是 4 并且最多有 3 个对象?

4

3 回答 3

1

你没有正确看待这个。并非所有“冰岛语”对象都符合此行的垃圾收集条件。并且每个“冰岛”对象都有另一个对象,特别是 Long,当它包含“冰岛”对象超出范围和/或不再具有对其的实时引用时,它也有资格进行垃圾收集。

在此示例中,原始 i2 对象和“属于它”的 Long 直到 System.log 行之后才符合垃圾收集条件。

于 2013-05-20T17:49:19.190 回答
1

假设“at”是指“恰好在之前”(就像我们对断点所做的那样)。

如果您严格遵循语言规范,根据我的统计,有 2 个Icelandic对象符合垃圾回收条件,每个对象包含 1 个Long,因此总共有4 个对象符合条件

然而,在实际实现中,通过他们通常使用的所有优化,许多其他数字是可能的。例如:

  • JIT 可能会告诉 GCargs在该点以下从未使用过,因此在它“正式”超出范围之前它是合格的(然后加 1)。但是有了这种优化,剩下的Icelandic对象及其Long(再加上 2 个)也将如此。
  • JVM 可以选择Long在任意范围内实习对象,因此实习值不会被垃圾收集(在这种情况下,减 2 或 3,取决于先前的优化是否到位)。
  • 可能会发生任何数量的其他优化来更改该值。

在实践中你真的无法知道,除非你对执行运行时的实现有非常透彻的了解。

于 2013-05-20T17:55:49.910 回答
0

简短的回答是这个问题没有答案。

包含命令行参数的String[]可能在调用结束时符合 GC 条件。该Long值可能在也可能不在Long.valueOf.

分配给后续未读取的局部变量并不能保证对 GC 产生影响,因为分配可能会被优化,并且由于活性分析可能会重用变量,并且这可能会在 JIT 编译代码后发生变化。

于 2013-05-20T17:50:51.727 回答