6

Taken from the official Java tutorial by Oracle, see question 2 here (boilerplate by me).

public static void main(String[] args) {

    String[] students = new String[10];
    String studentName = "Peter Smith";
    students[0] = studentName;
    studentName = null;

    System.out.println(students[0]);

}

The answer says that studentName is not eligible for garbage collection since the array students still references it. However, the final line prints "Peter Smith", so to me it seems wrong that students[0] references studentName. Can someone please explain this?

Arsaceus
  • 293
  • 2
  • 19
cmeeren
  • 3,890
  • 2
  • 20
  • 50

4 Answers4

7

I would like to explain with the help of diagrams step by step.

String studentName = "Peter Smith";

After first line, a String is created in the String pool and a reference name studentName is pointing towards it.

Part1

students[0] = studentName;

At this point, another reference students[0] is pointing to the same object as shown in the below diagram. Now 2 references are pointing to the same object created in memory.

Part2

studentName = null;

After this point, the reference of studentName will point to null i.e. it is pointing to no object. But reference of students[0] is still pointing to the String object (Peter Smith) created.

enter image description here

Clearly after the third statement, one reference is pointing to null but one reference is still pointing to the Object created. Therefore the object is not eligible for garbage collection.

Hope it helps.

Update : Sorry if I have messed up with the variable names. But I hope you get the idea.

thedarkpassenger
  • 7,158
  • 3
  • 37
  • 61
5

You're confusing the referencing variables (studentName and students[0]) with the object that they reference ("Peter Smith"). studentName and students[0] both reference the String object "Peter Smith". Once neither of them reference "Peter Smith"--and assuming that there are no other references elsewhere--that object will be eligible for garbage collection. The references themselves go away when they go out of scope.

The tutorial got it wrong. There is no object studentName. studentName is a variable that, at one point, holds a reference to "Peter Smith" and at another point is null. Similarly, students[0] is one element in an array of memory locations that holds a reference to "Peter Smith" (the same String object). The tutorial confuses the idea of variables with the objects they reference.

I might speculate that they do this to avoid going into the details of memory usage. That's something of an advanced topic. But their explanation IMO causes more confusion than it prevents.

Erick G. Hagstrom
  • 4,873
  • 1
  • 24
  • 38
  • 1
    I did indeed get this wrong. However, the tutorial answer says "The object `studentName` is not eligible either because `students[0]` still refers to it." But isn't this wrong? Doesn't `students[0]` point to the string "Peter Smith", and not `studentName`? The tutorial answer seems to me to be mixing this up too. – cmeeren Feb 01 '16 at 21:01
  • I don't blame you for being confused. The answer to that question (Oracle tutorial #2) is poorly worded. – Erick G. Hagstrom Feb 01 '16 at 21:04
1

As far as I know, your code runs like this:

  1. String[] students = new String[10]; - Create students array. The students variable is now a pointer to the object in memory.
  2. String studentName = "Peter Smith"; - Assign the variable studentName the pointer to the value "Peter Smith". The studentName variable does not actually contain the name value.
  3. students[0] = studentName; - Assign the first element in the array the pointer to the the value "Peter Smith".

At this point both studentName and students[0] are pointing to the same thing, but neither of them contain the value itself.

  1. studentName = null; - this sets the reference to null. It does not clear the underlying memory allocation.
  2. System.out.println(students[0]); - This will print Peter Smith. The 0 element in the array contains a pointer to the original string object.

Because the array still contains a reference to the "Peter Smith" object, even though the original pointer (studentName) has been set to null, the object will not be eligible for garbage collection.


If you want to read a bit more about the way Java handles values and pointers these posts may help:

Community
  • 1
  • 1
Tiz
  • 680
  • 5
  • 17
1

Think that there is an object pointing a memory area which has "Peter Smith" in it .when another object assigned to this object this second object is also pointing this memory cell.after that someone wants first object not to point any memory cell,but second one still points the same cell which still has the "Peter Smith" value in it so this is why last line prints the name. I think it is clear that jvm can not delete first object since it has still value, also even though second object has no pointer address someone else is still using it.(it is not the case if the seconds one is pointing an address or not) it is still in use by some one else

daemonThread
  • 243
  • 2
  • 12