2012-09-02 110 views
2

这个问题就像是我以前one 考虑:垃圾收集问题

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(); 
13. Icelandic i3 = new Icelandic(); 
14. i3 = i1; i1 = i2; i2 = null; i3 = i1; 
15. } 
16. } 

当达到14行,有多少个对象符合垃圾收集器?

A. 0

B. 1

C. 2

D. 3

E. 4

F. 6

我选择了A,但正确的答案是E,但我不知道为什么?

+3

哪里是线14? – vainolo

+0

我不明白它是如何成为'E'的,因为你只创建三个对象实例(忽略可能在'Icelandic'构造函数内创建的任何对象)。除非他们说'args'也是垃圾收集的候选人,理由是main()'将返回并终止程序。 – aroth

+0

@vainolo它在通知了'weight'字段和 – peeyush

回答

8

我们将在main中创建的三个Icelandic对象称为A,BC

Initialy

  • i1=Ai2=Bi3=C;

i3 = i1

  • i1=Ai2=Bi3=A;

i1 = i2

  • i1=Bi2=Bi3=A;

i2 = null

  • i1=Bi2=nulli3=A;

i3 = i1

  • i1=Bi2=nulli3=B

在管线14中,站立的引用仅BIcelandic类型的对象。正在运行的程序中丢失了AC

被丢失每个Icelandic对象使垃圾收集器的两个对象收集,即。所述Icelandic对象本身和每IcelandicLong对象,这使垃圾收集的对象的总数。

由于makeNoise方法从来没有所谓的,他们不改变结果。

+0

如果makeNoise()方法**是**叫? –

+2

@Tomasz Nurkiewicz:它取决于'System.out.println'的实现。 –

+0

我认为我错过了一条规则,我认为当这个任务执行i1 = i2时,i1会引用A和B,但这似乎是错误的,这是真的,当那个屁股。执行i1不会再指A,只指B? –

2

如果仔细一看,毕竟i1i3的指配完毕后指向第二个对象,而i2指向null。这意味着两个Icelandic对象有资格使用GC。

每个Icelandic对象包含一个Long它使4个对象总共符合GC的条件。有趣的是,如果常数为12L,则答案将为:由于Long内部常量缓存导致的2。还请注意"whinny""vinny"来自常量池,不会被垃圾收集。

一旦您离开声明所有i1i2i3的范围,其余两个对象也符合GC要求。