I think it’s easier to understand if we rework the drawings, seeing what happens line by line.
Line 3:
Rabbit one = new Rabbit();
An instance of Rabbit
, for which the variable one
points. That is to say:
variable |
value |
one |
Rabbit created on line 3 |
Line 4:
Rabbit two = new Rabbit();
We create another instance of Rabbit
and assign in the variable two
:
variable |
value |
one |
Rabbit created on line 3 |
two |
Rabbit created on line 4 |
Line 5:
Rabbit three = one;
The variable three
points to the same place where one
is pointing (that is to the Rabbit
created in row 3):
variable |
value |
one |
Rabbit created on line 3 |
two |
Rabbit created on line 4 |
three |
Rabbit created on line 3 |
So far so good, we have 2 instances of Rabbit
and three variables, of which two (one
and three
) point to an instance of Rabbit
and a (two
) points to the other instance.
Line 6:
Now I think that’s the point that’s got you confused:
one = null;
Here we make the variable one
point to null
. That is, it stops pointing to the instance of Rabbit
:
variable |
value |
one |
null |
two |
Rabbit created on line 4 |
three |
Rabbit created on line 3 |
Note that only the variable one
is null, but three
still pointing to the instance of Rabbit
. And as each of the instances of Rabbit
still contains references to them, none is eligible for the GC.
But why three
is not null if it pointed to the same location as one
? This happens because the variables are not the object itself, but references to it. Making an analogy, imagine that I have two sheets of paper and write my address on both. Both have a reference to the same address, but none of them is the actual location (they only point to the location, only have a reference indicating where it is). If I tear/burn/grind one of the sheets, the other will remain intact and pointing to the address.
That’s what happens here: one
and three
pointed to the same object (to the instance of Rabbit
created in line 3). When leaving one
null (by "tearing the paper"), only it ceases to point to the object, but three
is not affected and continues pointing.
Line 7:
Rabbit four = one;
Here we create another variable (four
) and make it point to the same place where one
is pointing. But remember that one
now is null
, then four
will also be:
variable |
value |
one |
null |
two |
Rabbit created on line 4 |
three |
Rabbit created on line 3 |
four |
null |
That is, the two instances of Rabbit
continue to have references pointing to them, and therefore are not yet eligible for GC.
Line 8:
three = null;
Right now three
becomes null
:
variable |
value |
one |
null |
two |
Rabbit created on line 4 |
three |
null |
four |
null |
And see that now yes the instance of Rabbit
created in line 3 has no one else pointing to it, and therefore it becomes eligible for the GC.
Line 9:
two = null;
two
becomes null
, that is to say:
variable |
value |
one |
null |
two |
null |
three |
null |
four |
null |
So now the second Rabbit
(that was created in the book 4) no longer has any reference to it, and therefore also becomes eligible for the GC.
Line 10:
two = new Rabbit();
A new instance of Rabbit
, for which two
points out:
variable |
value |
one |
null |
two |
Rabbit created on line 10 |
three |
null |
four |
null |
It is worth remembering that call for System.gc()
nay ensures that the AG will be executed. The only thing we know is that certain objects are eligible to be collected, but when this is done it’s something we don’t control.
What you used to make the drawings?
– Natan Fernandes
@NatanFernandes https://balsamiq.com/wireframes/
– hkotsubo
thanks to everyone who helped @hkotsubo in particular for their attention, God bless you
– Deivson Bezerra