首页 > 解决方案 > 自定义链表中的垃圾回收

问题描述

假设这个自定义单链链表有以下数据;

1 2 3

我想删除第一个元素(恰好是 1)。为此,我只是将第一个指针移动到下一个,就像这样->

first = first.next;

现在,没有任何东西指向包含“1”的节点,而是指向某个节点(在这种情况下,是一个包含值“2”的节点)。

我从列表中取消链接的包含“1”的节点是否会被垃圾收集?

这是完整的实现:

public class LinkedList<E> {
    
   private Node<E> first;
   private Node<E> last;

   public E removeFromFront() {
       if(isEmpty()) {
           System.out.println("List is empty");
           return null;
       }
       E data = first.data;
       if(first == last) {
           first = last = null;
       } else {
           first = first.next;
       }
       return data;
   }

标签: javalinked-listgarbage-collection

解决方案


当然。

Java 有一个完整的垃圾收集器,而不是它的一些不完美的近似。没有'ARC'(自动引用计数,不能处理循环;例如Apple 的ObjC 实现使用,我认为是Swift)。

垃圾收集器的工作方式就像这样:

  • 采取所有“入口点”。这从当前使用的所有类加载器、所有线程以及任何这些方法中堆栈中任何位置的每个方法开始。
  • 然后从这些类加载器中获取所有类本身(不是它的实例,只是类;这无关紧要,除非你在 em 中有静态字段),以及所有局部变量(包括“this”引用和所有参数)所有堆栈上的所有这些方法。

那些不是垃圾。

然后,开始遍历所有非垃圾并扇出:找到它可以直接引用的所有内容。那也不是垃圾。继续:从新发现的非垃圾中扇出以找到更多的非垃圾。当找不到非垃圾时,声明其他所有东西都是垃圾,并在某个时候清理它(注意垃圾不可能将自己变成非垃圾,所以没有必要马上做) .

在这种情况下,没有静态字段或任何活动代码对曾经是first节点对象的引用,所以这是垃圾,给定这个垃圾实例你可以达到的东西是完全不相关的。这些参考文献没有被查看;从垃圾中可以到达的任何东西都无关紧要。

注意:实际垃圾收集器的工作方式完全不同。但是他们表现得像上面那样工作;如果没有,它们就不是垃圾收集器规范的有效实现。因此,它们引入了世代概念,并且可能使用引用计数作为提示,但在您描述的场景中,first无论您使用哪个垃圾收集器的 impl,都将其视为垃圾。


推荐阅读