1

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");
    }    
}
4

2 回答 2

12

These are steps of your program:

    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

So the last diagram concludes that only 2 objects are ready for garbage collection. I hope I am clear. You can see object names as references to the objects.

EDIT:

As said by BalusC, Long weight = 1200L is also object. So 2 more objects each for i1 and i3 are eligible or garbage collections. So in all 4 objects are eligible or garbage collection.

于 2011-11-25T16:49:09.183 回答
1

作为一个非常简单的经验法则,如果对象的所有字段都复制到局部变量(优化程序转换)并且对对象的所有引用都设置无效的。

引用“Java VM 规范”

12.6.1 实现终结 每个对象都可以通过两个属性来表征:它可能是可达的、终结器可达的或不可达的,它也可能是未终结的、可终结的或已终结的。

可达对象是可以从任何活动线程的任何潜在持续计算中访问的任何对象。可以设计优化程序的转换,将可到达的对象的数量减少到比那些天真地认为是可到达的要少。例如,编译器或代码生成器可能会选择将不再使用的变量或参数设置为 null,以使此类对象的存储空间可能更快地被回收。

讨论

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

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

于 2011-11-25T17:21:27.343 回答