References and Variables in Java
An object is garbage when no variable refers to it, and the system reclaims its memory
A Variable Is Not the Object
Most of the time spent with objects so far has been about creating them. Java also has to deal with the other end of an object's life: what happens when it is no longer needed. In Java, that destruction happens automatically rather than through a deliberate instruction from the programmer.
Because destruction is automatic, it is tempting to assume that one action, such as assigning null to a variable, is what tears the object down. The rest of this article tests that belief against how Java actually decides an object is no longer needed. Start with a deliberately unrealistic pair of statements. The first line creates a Student object and stores a reference to it in the variable std. The second line overwrites std with null.
What do you think happens?
After the second line runs, what has happened to the Student object?
Reveal answer
It has become inaccessible. Java describes such an object as garbage, and the memory it occupies can be reclaimed and used for another purpose.
The assignment changed the variable std, not the object. The object still exists in memory right after the second line runs, but nothing refers to it anymore. The source does not say that reclamation happens at the instant of the assignment, so the correct idea is that the object is garbage and its memory can be reclaimed.
Variables Hold References
A variable such as std does not contain the Student object itself. It holds a reference, which is a way of pointing to an object. The object lives separately, and the variable is one of the things that points at it. Diagram 1 shows this relationship: the variable sits in one group, and the object it refers to sits in another.
The diagram captures the key idea of this article. The variable is one path to the object. As long as at least one such path exists, the object is in use. When every path is removed, the object has no remaining references, and the system can treat it as garbage.
Reassigning a Variable to Null
Here is the pair of statements from the opening, written as Java. The Student class is not defined here because the focus is on the variable, not on the class.
Student std = new Student();
std = null;- 1Line 1 new
Student()creates the object, and the assignment stores a reference to it in the variable std. - 2Line 2 std = null replaces that reference with null. The variable no longer points at the Student object.
- 3After line 2, the object itself has not been touched. Only the variable changed. The object has no remaining references, so it is garbage.
- Line 1 creates a Student object and stores a reference to it in std
- Line 2 overwrites the reference in std with null
The diagram shows the chain of events the code sets up. Only one transition is caused by the assignment: std moving from the object to null. The final state, where the object is garbage, depends on there being no remaining references. That condition is what the source identifies as making an object garbage.
Several Variables Sharing One Object
After an object has been used for a while, several variables may hold references to it. The object only becomes garbage once every one of those references has been dropped. The example below is an original illustration of that idea, not a line from the source.
Dropping references one at a time
Two variables, a and b, both refer to the same Student object. Follow the references as a and then b are set to null. At which step does the object become garbage?
- 1Step 1: both variables refer to one object
Assume a and b both hold a reference to the same Student object. The object is reachable through two paths.
- 2Step 2: a is set to null
The reference through a is removed, but b still refers to the object. The object is still reachable, so it is not garbage. Changing one variable did not change the object.
- 3Step 3: b is set to null
The last remaining reference is removed. No variable refers to the object, so the object is now garbage and its memory can be reclaimed.
The object becomes garbage at step 3, when the last reference is dropped, not at step 2 even though a reference was removed there.
When you are checking whether an object is still needed, count the references that could still reach it, not just the one you are looking at. Removing one reference proves nothing on its own if another variable still points to the object.
Dangling Pointers Versus Memory Leaks
The source describes two errors that arise in languages where the programmer must delete unused objects manually. A dangling pointer error happens when a programmer deletes an object that still has references to it, so the program later tries to use something that is no longer there. A memory leak happens when a programmer neglects to delete an object that is no longer in use, so memory fills with objects nothing can reach.
| Error | What went wrong | What the program sees | Direction of the mistake |
|---|---|---|---|
| Dangling pointer error | An object was deleted while it still had references | A reference to something that is no longer there | Deleted too early |
| Memory leak | An object no longer in use was never deleted | Memory filling up with objects nothing can reach | Deleted too late or never |
The two errors are opposites: one deletes too early, and the other deletes too late or never.
Who Handles Cleanup in Java
In Java, the source states that garbage collection is the system's responsibility rather than the programmer's. Because the collector decides which objects are garbage, the two errors described above are not possible in the same way. The programmer no longer tracks individual deletions.
Java's collector looks at which objects are still reachable through references and reclaims the ones that are not. This is why reference tracking matters: the collector's decisions depend entirely on which variables still point at which objects.
The programmer's job shifts. Rather than managing deletions, you make sure objects that are still needed remain referenced, and objects that are finished are no longer referenced. Those two decisions are where a programmer's attention belongs.
Mistakes When Thinking About Object Lifetime
Common mistake Assuming that assigning null immediately deletes the object
What it looks likestd = null; is followed by an expectation that the Student object vanishes at that exact moment.Why it failsThe assignment changes the variable, not the object. The object becomes garbage only when no reference to it remains.
Do this insteadAsk whether any other reference still reaches the object before concluding that it is garbage.
Common mistake Removing one reference and assuming the object is garbage
What it looks likea = null; is treated as the end of the object when b still refers to it.Why it failsThe object is still reachable through b, so it is not garbage.
Do this insteadCount all references to the object and drop every one of them before treating the object as garbage.
Common mistake Thinking automatic cleanup means references never need attention
Why it failsThe collector decides based on reachability. A forgotten reference keeps an object reachable.
Do this insteadKeep references only for objects you still need, and drop references to objects you have finished with.
Practice Tracing References
Consider these four statements in order: Student a = new Student(); Student b = a; a = null; b = null; At which statement does the Student object become garbage, and why? Trace which variables refer to the object after each line before you answer.
Hints
- After line 2, both a and b refer to the same object.
- Check whether any variable still refers to the object after each assignment.
- The answer is the statement that removes the last remaining reference.
Key Takeaways
- An object is garbage when no variable refers to it, and the system reclaims its memory.
- A variable holds a reference to an object. Reassigning that variable changes the reference, not the object itself.
- An object shared by several variables remains reachable until every one of those references has been dropped.
- A dangling pointer error deletes an object that is still referenced, while a memory leak fails to delete an object that is no longer used.
- Java's garbage collection is the system's responsibility, so the programmer's focus is keeping needed objects referenced and dropping references to finished ones.