垃圾收集模拟OCPJP考试

时间:2011-11-25 16:33:18

标签: java ocpjp

在下面显示的类中执行i3 = null;时,有四个对象符合垃圾回收的条件。我添加了评论来解释我是如何得到这个答案的。我的推理是否正确?

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

    public static void main(String args[]){
        /**
         * 2 objects created
         */
        Icelandic i1 = new Icelandic();

        /**
         * 2 objects created
         */
        Icelandic i2 = new Icelandic();

        /**
         * 2 objects created
         */
        Icelandic i3 = new Icelandic();

        /**
         * i3 is now pointing at i1, original Icelandic() referred to by i3 now
             * has no reference -  2 objects now have no reference
         */
        i3 = i1;

        /**
         * i3 is now pointing at i1, original Icelandic() referred to by i1 now
             * has no reference -  2 objects now have no reference
         */
        i1 = i2;

        /**
         * Total of six objects created, 4 objects no longer have a reference so 4
             * can be garbage collected.
         * 
         * Setting to null below doesn't make any difference to garbage collector
             * as objects now do not have a reference
         */
        i2 = null;
        i3 = null;
    }
}

interface Animal {
    void makeNoise();
}

class Horse implements Animal{
    Long weight = 1200L;

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

2 个答案:

答案 0 :(得分:12)

这些是您的计划的步骤:

    Icelandic i1 = new Icelandic();
    Icelandic i2 = new Icelandic();
    Icelandic i3 = new Icelandic();

enter image description here

    i3 = i1;
    i1 = i2;

enter image description here

    i2 = null;
    i3 = null;

enter image description here

因此,最后一个图表得出结论,只有2个对象可以进行垃圾回收。 我希望我很清楚。您可以将对象名称视为对象的引用。

修改

正如BalusC所说,长重= 1200L也是对象。因此,i1和i3各有2个对象是合格的或垃圾收集。所以在所有4个对象都符合条件或垃圾回收。

答案 1 :(得分:1)

作为一个非常简单的经验法则,如果程序的行为不会改变,如果对象的所有字段都被复制到局部变量,那么java中的对象可以被垃圾收集(优化程序转换) )并且对该对象的所有引用都设置为null。

引用“Java VM Spec”

  

12.6.1实施定稿   每个对象都可以用两个属性来表征:它可以是可达的,终结器可达的,或者是不可达的,它也可以是未终结的,可终结的或最终的。

     

可到达对象是可以从任何活动线程的任何潜在持续计算中访问的任何对象。可以设计优化程序的转换,以减少可达到的对象的数量,使其少于可以被认为可达的对象的数量。例如,编译器或代码生成器可以选择设置一个不再用于null的变量或参数,以使这种对象的存储可以更快地回收。

     

讨论

     

如果对象字段中的值存储在寄存器中,则会出现另一个示例。然后程序可以访问寄存器而不是对象,并且永远不会再次访问对象。这意味着该对象是垃圾。

因此,在您的情况下,由于没有任何对Icelandic个对象的引用被解除引用,所以它们都可能立即被垃圾收集。由于没有任何解除引用i1i3,优化编译器可以自由地将i3 = new Icelandic()之后的所有内容作为无操作删除并立即收集所有六个对象。