Number of objects to collect garbage

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 suitable for the garbage collector?

and. 0 B. 1 C. 2 D. 3 E. 4 F. 6

Answer: E. Why?

+3


source to share


5 answers


After line14, only the original i2 object is alive, the reference does not refer to the original i1 and i3, so they are eligible for the garbage collector, and this object has a base type, long field, will lose it, so 2 * 2 = 4;



+1


source


The question, and especially insisting on this particular "correct" answer 4, doesn't make much sense as it makes several assumptions about how the JVM works that are naive at best or just plain wrong.

The first thing it does wrong is to assume how many objects have ever been created.

The method main

creates three instances Icelandic

that have an inherited weight

value-initialized field 1200L

. The value is 1200L

converted to an instance Long

through automatic boxing using a method Long.valueOf

that is permitted but not required for a cache of frequently requested values. Therefore, we cannot predict the number of instances created here Long

, it can be one or three, but even two are possible if caching does not work for all calls for some reason.

The code is then played back with local variables containing three instances, and should only hold one of those instances "after" line 14, but there is no associated code after that line for which this state might be relevant. The only thing that happens is after this line is returned from the method main

, so after line 14 all local variables go out of scope.



Whether there is an execution point that may be associated with "after line 14" but is still in a method main

where exactly one instance Icelandic

is in scope depends on whether the line debug information is included in and how the compiler did the byte code instruction matching with these line numbers.

If the bytecode instruction return

inserted by the compiler is not linked to line 15, all instances created in the method main

may be garbage collected after line 14, but be aware that the instance will Long

reference the global cache and therefore not be eligible to be collected garbage. We simply cannot predict.

There is another aspect of JVM execution: optimization. The JVM is allowed to perform "escape analysis" and creation of elite objects as long as they do not affect the semantics of the programs. In your program, all objects are not used from the JVM point of view. So another forensic scenario is that this method main

never creates any object and then there is no object suitable for garbage collection at all.

+4


source


This way, every object has a Long object, so when every Icelandic object is marked for garbage collection, the value Long

it points to is also indicated. So after:

Icelandic i1 = new Icelandic();
Icelandic i2 = new Icelandic();
Icelandic i3 = new Icelandic();
i3 = i1; i1 = i2; i2 = null; i3 = i1;

      

the original i3 is lost and the original i1 is lost. i1 and i3 point to the original i2 backing it (and i2 points to zero, keeping nothing alive). This leaves 2 objects marked for garbage collection (original i1 and original i3) as well as the value Long

they pointed to, which gives you 4 items marked for garbage collection.

+2


source


enter image description here

I would go with Icelandic 2 eligible objects (objects 1 and 3). Since every Icelandic holds a Long object, it gives us 4.

+2


source


Important stuff here

Icelandic i1 = new Icelandic();
Icelandic i2 = new Icelandic();
Icelandic i3 = new Icelandic();
i3 = i1; i1 = i2; i2 = null; i3 = i1;

      

So, it i3

loses its link immediately, so the original object is ready to be collected.

i1

and a i3

link i2

, so the original i1s object is ready to be collected.

Then it i2

loses its reference, so all 3 have zero and garbage collection.

I will personally go with 3. This is a pretty thoughtful question.

+1


source







All Articles