Reputation: 28
In Java, there is no reference pointing to an object, but one of the methods of this object is still on the call stack.
Is it possible that the garbage collector removes this object before its method is popped off the call stack, or does it wait until the method is popped off?
(please refer to my specific problem below)
Implementation of a simple singly linked list:
public class LIST
{
private LIST_ELEMENT begin = new END();
// some methods to add or remove elements
public void clear()
{
begin = new END();
}
public void insertSorted(DATA_ELEMENT dataNew)
{
begin = begin.insertSorted(dataNew);
}
public void sort()
{
begin.sort(this);
}
}
public abstract class LIST_ELEMENT
{
public abstract LIST_ELEMENT insertSorted(DATA_ELEMENT dataNew);
public abstract void sort(LIST list);
}
public class END extends LIST_ELEMENT
{
@Override
public LIST_ELEMENT insertSorted(DATA_ELEMENT dataNew)
{
return new NODE(this, dataNew);
}
@Override
public void sort(LIST list)
{
list.clear();
}
}
public class NODE extends LIST_ELEMENT
{
private LIST_ELEMENT next;
private DATA_ELEMENT data;
public NODE(LIST_ELEMENT nextNew, DATA_ELEMENT dataNew)
{
next = nextNew;
data = dataNew;
}
@Override
public LIST_ELEMENT insertSorted(DATA_ELEMENT dataNew)
{
if(data.isSmallerThan(dataNew))
{
next = next.insertSorted(dataNew);
return this;
}
else
{
return new NODE(this, dataNew);
}
}
@Override
public void sort(LIST list)
{
next.sort(list);
list.insertSorted(data);
}
}
public interface DATA_ELEMENT
{
public boolean isSmallerThan(DATA_ELEMENT dataCompare);
}
Having implemented this sorting algorithm, is it safe?
Can the garbage collector remove the data from the NODE objects after the list was cleared (so the call
list.insertSorted(data);
does something unexpected), or does the method on the call stack count as a reference to the object so that the data attribute is valid for the entire duration of the call of LIST.sort?
Is it guaranteed that the object is not removed during this time?
In my testing, the call to LIST.sort always sorted the list as expected.
Upvotes: 0
Views: 1763
Reputation: 298203
It seems, you have a fundamentally wrong understanding of what a garbage collector does. You wrote
Can the garbage collector remove the data from the NODE objects after the list was cleared (so the call
list.insertSorted(data);
does something unexpected), or does the method on the call stack count as a reference to the object so that the data attribute is valid for the entire duration of the call of LIST.sort? Is it guaranteed that the object is not removed during this time?
A garbage collector will never remove something. A removal is an action in your application logic, like changing the next
fields of your node objects. A garbage collector will never perform such actions.
Likewise, the semantics of your “list” do not affect the garbage collector. To the garbage collector, an instance of your LIST
class is just an object with a reference to another object. When the garbage collector decides to reuse the memory of the LIST
instance, it does not affect the LIST_ELEMENT
you might be still working on. It does not collect “the entire list”, as to the garbage collector, there is no such thing as a list.
As a simple rule of thumb, unless you write code with a special interaction with the garbage collector, like a finalizer or cleaner, or are dealing with the special weak, soft, or phantom reference objects, you will never notice the garbage collector’s activity. It will reuse the memory of those objects whose memory is not needed by the application, in other words whenever your application won’t notice it.
That said, contrary to the other answers, executing an instance method does not prevent the garbage collection of an object that is otherwise unused. But how could it be otherwise unused? That would imply that even the caller has no other reference to the list (or won’t use it). So who cares about the contents of the list, if no reference to the list exist? The other scenario would be that the JVM has optimized the code such that it doesn’t need the memory of the object, e.g. because it keeps all field values in CPU registers. You would again not notice anything, as the behavior of the program remains the same.
A real-life example has been documented in finalize() called on strongly reachable objects in Java 8 where an object truly got finalized while a method invocation on the object was ongoing. But as said, such things can only have a perceivable effect on the application’s behavior when you interact with the garbage collector explicitly. In the linked Q&A, it was a finalizer producing a noticeable effect.
Upvotes: 3
Reputation: 5207
In Java, there is no reference pointing to an object, but one of the methods of this object is still on the call stack.
This cannot happen. If a method is running, there is a reference to an object whose method was called.
Is it possible that the garbage collector removes this object before its method is popped off the call stack, or does it wait until the method is popped off?
As long as method is running, there is a reference to the object. That's why such object cannot be removed.
Upvotes: 1