How to distinguish object and variable in java - java

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;
....

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.

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.

Related

Java Garbage Collection with Assignment of Variables

I have been going through the Java tutorials on the Java website and have been left confused with an answer they gave to a question.
The question is as follows: "The following code creates one array and one string object. How many references to those objects exist after the code executes? Is either object eligible for garbage collection?"
String[] students = new String[10];
String studentName = "Peter Smith";
students[0] = studentName;
studentName = null;
Answer: "There is one reference to the students array and that array has one reference to the string Peter Smith. Neither object is eligible for garbage collection."
Why is studentName not eligible for garbage collection? Nothing is pointing to studentName, and it's value is null.
studentName is a variable not an object - you garbage collect only objects.
The only objects in here, as mentioned are the created String[] and "Peter Smith", and both are reachable, and thus not eligable for GC.
studentName is reference to Object not an actual Object,
If you mean Object referred by studentName
String studentName = "Peter Smith";
then it is still being referred by students[0]
students[0] = studentName;
If you look at the documentation on that site it says the following in the summary page:
"The garbage collector automatically cleans up unused objects. An object is unused if the program holds no more references to it. You can explicitly drop a reference by setting the variable holding the reference to null."
Even though the reference to "Peter Smith" is released by studentName when it is set to null, the string array students still has a reference to that object so it's not eligible for garbage collection. The array itself also still has a reference to it. If you put this in a small program and run it and print out students[0] after this code block it will print "Peter Smith"

Strings - Stack and heap in java

I know that Strings are stored on the heap and the reference to them is stored on the stack. So in the code below one would point to "John" on the heap from the stack and likewise two would point to "Smith" on the heap from the stack.
So what happens when i do one = two?
Does one now point to where two points to because two contains a reference to a point on the heap or does it change the "John" on the heap to "Smith"?
String one;
one = "John";
String two = "Smith"
one = two;
In your example, one now points to the same place as two. The original string on the heap "John" becomes garbage and is subject to garbage collection.
It's not possible to see in this example because String is immutable, but if these were mutable data structures such as an ArrayList, then modifying the object through one would make the same change visible through two, because they point to the same object.
Now one will point to the two .Since all string are immutable then when they are created then they are stored in heap and referenced by variable but when you make or assign new variable to same string then it will not explicitly create new string but just reference to same string which is in heap
from above picture you can easily understand the concept of immutability.
for reference Where does java reference variable stored?

Storing objects in array of objects

Basically i want to add students to a class list. Assuming i have the following code
public class ClassList {
//Constructor methods...
private Student [] studList = new Student [20];
public boolean addStudent (Student newStudent)
{
studList[14] = newStudent;
}
}
Does studList[14] add a reference to newStudent object or copies that object into the studList[14] student object?
As far as i understand newStudent object will get deleted when the method addStudent() is called a second time. So studList[14] will point to null then? What if i want studList[14] to persist throughout the code execution?
Sorry if it is hard to understand, i do not know how to explain my query easier...
There's one fundamental rule in Java that you have to wrap your head around:
The only way you can access an object is via its reference. And the only values that variables can hold are references(*). That's true for local variables, parameters, instance fields and static fields: they all are the same in this respect.
The object itself is never "contained" in a variable.
This directly leads to the answer to your first question:
The reference is copied into the array (as an array can only hold references(*), never objects).
This also mean that "newStudent being deleted" is not actually a big deal: it's just another reference to the same object, and if it goes away nothing much happens.
Now, if all references to a given object are removed (or no longer reachable), then the object itself becomes eligible for garbage collection, but that's not a bad thing, because you could not access it anymore anyway.
(*) ... or primitive values, but we'll ignore those for this dicussion.
The assignment doesn't copy the object. It just adds a reference to the object into the array.
An object gets deleted by the garbage collector after there are no more references to it anywhere. You don't need to worry too much about this process, because it's kind of invisible most of the time; and once there are no references to an object, you couldn't have used it anyway.
Perhaps you want to be able to pass in an int to your method, to tell it which entry in the array to set, instead of always setting entry number 14?
You should have a look at the JLS about types, values and variables:
The values of a reference type are references to objects.
If there is no remaining reference (aside weak ones) to an object it will be garbage-collected out of the heap.
If you call two times: addStudent(new Student());
the first Student object created is qualified for GC since you have no other reference variable "pointing" to the object.

Is this java Object eligible for garbage collection in List

What I am asking might be a stupid question so please pardon me for that.
So it goes like this :
List<Boss> bossList = new ArrayList<Boss>();
Boss b = null;
for(Employee e : List<Employee> myList){
b = new Boss();
b.setEmployee(e);
bossList.add(b);
b = null;
}
So in above scenario, I am creating lot of Boss objects and then de-referencing them(I know I don't need to write "b = null", but i did it for clarity of my question). In normal scenario, I would have marked them to garbage collection, by doeing this, but because in this scenario, I am adding those Boss objects in List collection, are they marked for GC or not? If not then why? And how does List collection work internally to hold references for each Object added, so as to avoid garbage collection?
[EDIT]
The scope of question is only limited to the individual Boss objects created in for loop, considering that this method returns the reference of the List to the outside world.
The Boss objects will not be collected by the GarbageCollector because they are still referenced in the code block that you are posted. bossList is an ArrayList which has an internal array of Object thus holding references to those objects which are added to it.
I such a situation not only the references by you are considered but all referneces in all objects involved.
EDIT: Since you are returning the List in your code the objects will not be marked for garbage collection until the list is no longer referenced in your program.
ArrayList has Object[] elementData internally. When you added b to bossList ArrayList assigned elementData[0] = b. So when you assigned null to b the instance of Boss is still referenced from elementData[0] and cannot be GCed. But since ArrayList instance is referenced only from method's variable after the method returns both ArrayList and Boss instances will be eligible for GC.
Here's what really happens with your code :
Since java is pass by reference, whenever you add b to bossList, bossList starts referencing the memory location which b is pointing to. So when b nullified only link from b to the reference is broken. Thus keeping the object accessible through bossList.

Java - why does assigning "null" to variable does not make it available for GC? (In this code snippet)

I was going through the online tutorial provided by oracle. One of the exercises has a question as follows:
The following code creates one array and one string object. How many references to those objects exist after the code executes? Is either object eligible for garbage collection?
...
String[] students = new String[10];
String studentName = "Peter Smith";
students[0] = studentName;
studentName = null;
...
Answer: There is one reference to the students array and that array has one reference to the string Peter Smith. Neither object is eligible for garbage collection.
(http://docs.oracle.com/javase/tutorial/java/javaOO/QandE/objects-answers.html)
Surely the last line means studentName is eligible for GC? Really confused, and I think this means I have not understood the nature of "null" and also object referencing properly, which is why I ask.
Before assigning null to studentName there are two references to "Peter Smith" (studentName and students[0]). After null is assigned to studentName, "Peter Smith" is still referenced by students[0]
What are the objects, actually, that cannot be garbage collected? "Peter Smith" and the String[10] array. Note these are the objects themselves, not the references to the objects! It is enough that just one reference exists to avoid garbage collection.
I use a mental trick which is to be verbose while reading code. It is easy to say "String" (vague) when what you mean is "String object" (the words in the String) or "String reference" (the variable pointing to the words) so this trick avoids this confusion.
Rewriting the pseudocode with my mental trick, labeling everything as object or reference the way I do in my mind:
1 String[] OBJECT student REFERENCE = new String[10] OBJECT;
2 String OBJECT studentName REFERENCE = "Peter Smith" OBJECT;
3 students[0] REFERENCE = studentName REFERENCE;
4 studentName REFERENCE = null;
In line 3 the String[0]_reference was pointed at the "Peter Smith" object. It is now clear that just the studentName reference was set to null but the "Peter Smith" object continues to exist and the array still points to it. Thus the objects aren't ever null, just one reference was nulled.
This page explains the fundamental java concept of references well (and how they are essentially just pointers)
http://javadude.com/articles/passbyvalue.htm
Though not about the question, it is directly relevant. Objects are referenced by pointers (references) in java. Understanding that should help a lot.

Categories

Resources