我在算法课程中浏览了队列的实现代码,并观察了作者使用的 dequeue()的代码:
private Node first, last;
private class Node {
String item;
Node next;
}
public boolean isEmpty() {
return first == null;
}
// Code segment in doubt
public String dequeue() {
String item = first.item;
first = first.next;
if (isEmpty()) last = null;
return item;
}
这里, first 和 last ,可以理解地分别指向队列中的第一个和最后一个元素。我对作者使用的 dequeue()中的代码持怀疑态度。因为,他只是在做:
first = first.next;
未将 first.next 分配给 null 。它是否会留下一个悬空引用(或游荡),这将阻碍JVM的垃圾收集机制?我有点困惑, dequeue()的代码不应该这样吗? (我确信在C / C ++中代码应该如下所示,但想知道JAVA在这种情况下的预期行为)
public String dequeue() {
Node old;
old = first;
first = first.next;
old.next = null;
if (isEmpty()) last = null;
return old.item;
}
如果有人能够通过很好的例子向我指出一个涵盖这个主题的资源,我也将不胜感激。
答案 0 :(得分:2)
设置old.next = null
是不必要的,因为old
已准备好进行垃圾回收(first = first.next
分配会删除其上一次实时引用(一旦dequeue
退出))等等垃圾收集器不会跟踪它的任何引用。
答案 1 :(得分:1)
假设你在队列中有2个对象:A和B
first
指向A
和first.next
指向B
(换言之A.next == B
)
对A
的唯一引用是Queue#first
变量。当你这样做
first = first.next; // first == B
没有人再引用A
对象,因此它有资格进行垃圾回收。
答案 2 :(得分:0)
如果您的队列未实现为Doubly Queue
(意味着您可以访问队列中的.Next和.Prev),那么在将first
设置为first.next
后,就会有不是first
的引用或指针,然后垃圾收集线程将知道它(first
)需要收集垃圾(相关的内存将被释放)。
答案 3 :(得分:0)
只有活动对象的引用很重要。这些确定了哪些对象是活的。
如果某个对象具有对活动对象的引用,但未引用该对象,则会收集该对象。 (JVM不使用引用计数,也不需要更新它)
另一个案例涉及人们,如果两个对象相互引用(但没有其他事情)这也很好,因为只有可以从根节点(例如线程)访问的对象被保留,其他一切都被收集。