Queue dequeue()示例代码中的Java垃圾收集

时间:2013-05-20 15:42:20

标签: java garbage-collection

我在算法课程中浏览了队列的实现代码,并观察了作者使用的 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;
}

如果有人能够通过很好的例子向我指出一个涵盖这个主题的资源,我也将不胜感激。

4 个答案:

答案 0 :(得分:2)

设置old.next = null是不必要的,因为old已准备好进行垃圾回收(first = first.next分配会删除其上一次实时引用(一旦dequeue退出))等等垃圾收集器不会跟踪它的任何引用。

答案 1 :(得分:1)

假设你在队列中有2个对象:A和B

first指向Afirst.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不使用引用计数,也不需要更新它)

另一个案例涉及人们,如果两个对象相互引用(但没有其他事情)这也很好,因为只有可以从根节点(例如线程)访问的对象被保留,其他一切都被收集。