I get stuck in this problem in java docs. The second problem's answer said that after the code execute, "Neither object is eligible for garbage collection. The array students
is not eligible for garbage collection because it has one reference to the object studentName
even though that object has been assigned the value null. The object studentName
is not eligible either because students[0] still refers to it."
But I don't think studentName
and students
are object, they just variables to refer to objects, and they will not be garbage recycled. I think only the String "Peter Parker" is an object in the code below. What's wrong?
...
String[] students = new String[10];
String studentName = "Peter Parker";
students[0] = studentName;
studentName = null;
....
CodePudding user response:
This statement is fundamentally wrong on more levels than confusing objects and variables.
You are right in that it confuses names and objects, to the highest amount ever seen. Not only is “reference to the object studentName
” wrong as studentName
is not an object, “even though that object has been assigned the value null
” is even worse, as objects can not be assigned to null
and what is supposed to explain that setting a reference to null
does not imply that the referent becomes unreachable, is achieving the opposite.
But that’s not the end, as the entire logic is wrong. Let’s remove the names, to avoid that confusion. Then, the phrase reads as “The array … is not eligible for garbage collection because it has one reference to the object …”. That’s completely wrong. If X
has a reference to Y
, it does not prevent the garbage collection of X
, as only references to X
matter.
What may prevent the garbage collection of the array, is the variable students
holding a reference to it, but of course, an author who fails to distinguish between variables and objects, is not able to express this relationship.
It’s worth noting, that if students
is a local variable, it does not prevent the garbage collection of the array in every case, as explained in Can java finalize an object when it is still in scope? But skipping this in a tutorial may be acceptable for simplification, see also Lie-to-children.
Another issue is that objects created for string literals like "Peter Parker"
will stay in memory as long as there’s at least one piece of code in the JVM having a reference to it, as all string literals (and compile-time constants of type string) of the same contents evaluate to the same object.
If you want to go the route of simplified reasoning about garbage collection, the students
variable contains a reference to a String[]
array instance, which is prevented from garbage collection due to this reference, and the array contains a reference to a String
object, which prevents the String
instance from garbage collection (in addition to other references which may exist).
Most of the time, you shouldn’t try to guess what the garbage collector could collect, because the very purpose of the garbage collector is to remove the burden of thinking about this from the developer.
CodePudding user response:
Unfortunately, the doc does not clearly distinguish bewtween variables and objects. There are two objects in this snippet: the array new string[10]
and the string "Peter Parker"
. In line 1 the variable students
is set to a reference of the array object; in line 2 the variable studentName
is set to a reference of the string object; in line 3 the array element 0 is set to a reference to the string object; and finally in line 4 the variable studentName
is set to null
.
Now the array object cannot be garbage collected because the variable students
still holds a reference and the string objects cannot be garbage collected because the array element 0 still has a reference.
If there were a line 5 where the variable students
is set to null
as well, both objects could be garbage collected because both are no longer reachable (a string literal however is never garbage collected - but this for another reason). It does not matter that the array element 0 still has a reference to the string object in this case because the array object itself is no longer reachable.