Reputation: 47
Given:
interface Animal { void makeNoise(); }
class Horse implements Animal {
Long weight = 1200L;
public void makeNoise() { System.out.println("whinny"); }
}
public class Icelandic extends Horse {
public void makeNoise() { System.out.println("vinny"); }
public static void main(String[] args) {
Icelandic i1 = new Icelandic();
Icelandic i2 = new Icelandic();
Icelandic i3 = new Icelandic();
i3 = i1; i1 = i2; i2 = null; i3 = i1; //<-- line 14
}
}
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
answer is E. why?
Upvotes: 3
Views: 788
Reputation: 2037
I would go with Icelandic 2 objects eligible (object 1 and 3). Since each Icelandic holds a Long object, it gives us 4.
Upvotes: 2
Reputation: 298123
The question, and especially insisting on that particular “correct” answer of 4, doesn’t make much sense, as it draws several assumptions about how a JVM works which are naïve in the best case or simply wrong.
The first thing it does wrong is to assume to know, how many objects are ever created.
The main
method creates three instances of Icelandic
having an inherited field weight
initialized with the value of 1200L
. The value 1200L
is converted to a Long
instance via auto-boxing using the method Long.valueOf
which is allowed, but not required to cache frequently requested values. So we can’t predict the number of Long
instances created here, it might be one or three, but even two is possible if the caching did not work for all invocations, for whatever reasons.
Then the code is playing around with the local variables holding the three instances and is supposed to hold only one of these instances “after” line 14 but there is no associated code after that line for which this state could have a relevance. The only thing which happens after that line is returning from the main
method so after line 14 all local variables are out-of-scope.
Whether there is a point of execution which can be associated with “after line 14” but still being in method main
where exactly one instance of Icelandic
is in scope depends on whether line debug information have been included in the class file and how the compiler did map byte code instructions to these line numbers.
If the return
byte code instruction inserted by the compiler is not associated with line 15, all instances created in the main
method might be garbage collected after line 14 but keep in mind that the Long
instance might still be referenced from a global cache and hence not be eligible to garbage collection. We simply can’t predict.
There is another aspect of JVM execution: optimization. JVMs are allowed to perform “escape analysis” and elide object creations if they don’t have any impact on the programs semantics. In your program, all objects are unused from a JVMs point of view. So another legal execution scenario is that this main
method never creates any object and then there are no object eligible for garbage collection at all.
Upvotes: 4
Reputation: 26
After Line14, Only original i2 Object is alive, no referemce is point to original i1 and i3, so they are eligible for the garbage collector, and this object has a base type, a long field, lose it to, so 2*2 = 4;
Upvotes: 1
Reputation: 26058
So each object holds a Long object, so when each Icelandic object is marked for garbage collection, so is the Long
value it pointed to. Therefore after:
Icelandic i1 = new Icelandic();
Icelandic i2 = new Icelandic();
Icelandic i3 = new Icelandic();
i3 = i1; i1 = i2; i2 = null; i3 = i1;
the original i3 object is lost, and the original i1 value is lost. i1 and i3 both point to the original i2 keeping it alive (and i2 points to null, keeping nothing alive). This leaves 2 objects getting marked for garbage collection (the original i1 and original i3) as well as the Long
value they pointed to, giving you 4 items marked for garbage collection.
Upvotes: 2
Reputation: 2715
The important stuff is here
Icelandic i1 = new Icelandic();
Icelandic i2 = new Icelandic();
Icelandic i3 = new Icelandic();
i3 = i1; i1 = i2; i2 = null; i3 = i1;
So i3
loses its reference right away so the original object is ready for collection.
i1
and i3
reference i2
so i1s original object is ready for collection.
Then i2
loses its reference so all 3 are null and garbage collected.
I'd personally go with 3. That's a pretty thought provoking question.
Upvotes: 1