I am preparing for OCPJP, and I got stuck at the following mock exam question:
Given:
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. }
When line 14 is reached, how many objects are eligible for the garbage collector?
A. 0
B. 1
C. 2
D. 3
E. 4
F. 6
Their correct answer is E, i.e. four objects, but I'm not sure why. From my point of view, i2 and its weight will get eligible for garbage collection. Perhaps I'm missing something, please advise.
Lets call Icelandic()
on line 11 IceA
, line 12 IceB
, and so forth.
After creation
i1 = IceA
i2 = IceB
i3 = IceC
After i3 = i1
i1 = IceA
i2 = IceB
i3 = IceA
After i1 = i2
i1 = IceB
i2 = IceB
i3 = IceA
After i2 = null
i1 = IceB
i2 = null
i3 = IceA
After i3 = i1
i1 = IceB
i2 = null
i3 = IceB
So only the Icelandic()
created on line 12 remains. Now, each Icelandic()
has a Long weight
, so IceA
and IceC
are now unreferenced, meaning 4 objects (IceA
, IceA.weight
, IceC
, IceC.weight
) are available for GC.
Other issues:
args
is stillargs
, they are not counting going out of scope in this questionLong weight
is not declared statically, so each instance of the class has aweight
object.
Let's call the first Icelandic object that is created "A", the second one "B", and the third one "C". After line 12, they are referenced by i1, i2, and i3, respectively.
Now, we do:
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
So, objects "A" and "C" are no longer referenced, and they along with their "weight" are eligible for garbage collection, so four objects total.
You will have 4 objects in the system, 3 Icelandic
instances and 1 Long
instance.
When you assign constant object to some variable, compiler uses kind of private static final Long long1200 = Long.valueOf(1200L);
object that is shared by all weight
instances.
Primitive type wrappers are immutable, so it is safe to do this optimization.
EDIT: probably I am wrong, because this would work this way if we referenced the same constant several times here, which is not the case
来源:https://stackoverflow.com/questions/13634766/eligible-variables-for-garbage-collection-in-java