Java中垃圾收集的合格变量

时间:2012-11-29 21:08:51

标签: java garbage-collection ocpjp

我正准备OCPJP,我被困在以下模拟考试问题中:

假设:

3. interface Animal { void makeNoise(); }

4. class Horse implements Animal {
5.     Long weight = 1200L;
6.     public void makeNoise() { System.out.println("whinny"); }
7. }

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

10.    public static void main(String[] args) {
11.        Icelandic i1 = new Icelandic();
12.        Icelandic i2 = new Icelandic();
12.        Icelandic i3 = new Icelandic();
13.        i3 = i1; i1 = i2; i2 = null; i3 = i1;
14.    }
15. }

当到达第14行时,有多少对象符合垃圾收集器的条件?

一个。 0

B中。 1

℃。 2

d。 3

电子。 4

F。 6

他们的正确答案是E,即四个物体,但我不知道为什么。从我的角度来看,i2及其重量将有资格进行垃圾收集。也许我错过了什么,请指教。

3 个答案:

答案 0 :(得分:8)

让我们在第11行Icelandic(),第12行IceA等处致电IceB,等等。

创建后

i1 = IceA
i2 = IceB
i3 = IceC

i3 = i1之后

i1 = IceA
i2 = IceB
i3 = IceA

i1 = i2之后

i1 = IceB
i2 = IceB
i3 = IceA

i2 = null之后

i1 = IceB
i2 = null
i3 = IceA

i3 = i1之后

i1 = IceB
i2 = null
i3 = IceB

因此只剩下第12行创建的Icelandic()。现在,每个Icelandic()都有Long weight,因此IceAIceC现在未被引用,意味着4个对象(IceAIceA.weight,{{ 1}},IceC)可用于GC。


其他问题:

  1. IceC.weight仍为args,他们不计算超出此问题的范围
  2. args未静态声明,因此该类的每​​个实例都有一个Long weight对象。

答案 1 :(得分:3)

让我们调用第一个创建“A”的冰岛对象,第二个称为“B”,第三个称为“C”。在第12行之后,它们分别由i1,i2和i3引用。

现在,我们这样做:

i3 = i1; // object "C" is no longer referenced, object "A" is now referenced by i1 and i3
i1 = i2; // object "A" is just referenced by i3, object "B" is referenced by i1 and i2
i2 = null; // object "B" is just referenced by i1 now
i3 = i1; // object "B" is referenced by i1 and i3, object "A" is no longer referenced

因此,不再引用对象“A”和“C”,它们及其“权重”符合垃圾收集条件,因此共有四个对象。

答案 2 :(得分:2)

系统中将有4个对象,3个Icelandic个实例和1个Long个实例。

当您将常量对象分配给某个变量时,编译器会使用所有private static final Long long1200 = Long.valueOf(1200L);个实例共享的weight对象。

原始类型包装器是不可变的,因此可以安全地进行此优化。

编辑:可能我错了,因为如果我们在这里多次引用相同的常量,这将是这样的,事实并非如此