Java中垃圾收集的合格变量
我正在准备,我被困在下面的模拟考试题上: 鉴于:Java中垃圾收集的合格变量,java,garbage-collection,ocpjp,Java,Garbage Collection,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.
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行时,有多少对象符合垃圾收集器的条件
A.0
B.1
C.2
D.3
E.4
F.6
他们的正确答案是E,即四个物体,但我不知道为什么。在我看来,i2及其重量将符合垃圾收集的条件。也许我遗漏了什么,请告知。让我们在第11行IceA
、第12行ICE
上调用Icelandic()
创造之后
i1 = IceA
i2 = IceB
i3 = IceC
在i3=i1之后
i1 = IceA
i2 = IceB
i3 = IceA
i1 = IceB
i2 = null
i3 = IceB
在i1=i2之后
i1 = IceB
i2 = IceB
i3 = IceA
在i2=null之后
i1 = IceB
i2 = null
i3 = IceA
在i3=i1之后
i1 = IceA
i2 = IceB
i3 = IceA
i1 = IceB
i2 = null
i3 = IceB
因此,只有在第12行创建的Icelandic()。现在,每个Icelandic()
都有一个Long weight
,因此IceA
和IceC
现在都没有引用,这意味着GC可以使用4个对象(IceA
,IceA.weight
,IceC.weight
)
其他问题:
args
仍然是args
,在这个问题中,它们不算超出范围
Long weight
不是静态声明的,因此类的每个实例都有一个weight
对象
系统中将有4个对象,3个Icelandic
实例和1个Long
实例
当您将常量对象分配给某个变量时,编译器使用某种类型的private static final Long 1200=Long.valueOf(1200L)所有weight
实例共享的code>对象
原语类型包装器是不可变的,因此进行此优化是安全的
编辑:可能我错了,因为如果我们在这里多次引用同一个常量,就会这样做,但事实并非如此。让我们将创建的第一个冰岛对象称为“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”不再被引用,它们连同它们的“权重”都有资格进行垃圾收集,因此总共有四个对象。它们的问题有点傻,因为垃圾收集在程序终止时是不相关的(在第14行)…只是澄清一下-您确定weight
是Long
而不是Long
(对象,不是原语)?等等…这不完全取决于此程序的调用方式吗?字符串是对象,因此提供的任何参数都会更改对象的数量。那些String
在字符串常量池中,因此它们不符合垃圾收集的条件(至少在问题的意义上)。是的,我确定权重很长,我对整个代码进行了复制粘贴。权重呢?但是在第14行,所有的i1
、i2
和i3
都超出了范围,所以ICE
当然也可以是GC'd?@DNA:这是我最初的答案,但答案是6。显然,提问者希望在事情超出范围之前知道gc可以使用什么。啊,措辞糟糕的试题的乐趣;-)但是所有这些引用都超出了范围,因此不会阻止其中任何一个的GCobjects@DNA,我认为“到达第14行时”是指退出main()
之前。显然,如果答案是4,这就是问题作者的意图。@DNA:我同意你的看法,但我认为提问者说的是“在第14行之前”,而不是“在变量超出范围之后”。啊,这可以解释它——它完全改变了问题的含义,使第13行的所有混乱变得相关(否则,这是一个相当残酷的考试题转移!)对,最好让问题编写者插入一行实际的代码(比如System.out.println()
或类似的东西)在第14行,而不是右大括号。您是半正确的:编译器或Long实现正在优化实例以获得较小的数字,因此它只是一个。对于较大的数字,不再是:当然,这是运行时优化的Long.valueOf()
,我认为编译器也会不断优化,这似乎是错误的