符合垃圾收集器条件的对象

时间:2013-05-20 17:42:46

标签: java garbage-collection

鉴于:

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个对象?

3 个答案:

答案 0 :(得分:1)

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

在此示例中,原始i2对象和“属于它”的Long在System.log行之后才有资格进行垃圾回收。

答案 1 :(得分:1)

假设“at”表示“完全在之前”(就像我们对断点一样)。

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

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

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

除非你对执行运行时的实现有一个非常透彻的了解,否则你实际上无法知道。

答案 2 :(得分:0)

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

包含命令行参数的String[]可能在调用结束时符合GC的条件。 Long值可能位于Long.valueOf内部的缓存中,也可能不存在。

分配给随后未读取的局部变量不能保证对GC有影响,因为可以优化分配并且由于liveness analysis可以重用变量,并且这可能在JIT编译代码后发生变化。