自定义链表中的垃圾回收

Garbage Collection in Custom Linked List

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

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;
   }

当然可以。

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

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

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

那些不是垃圾。

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

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

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