Java 垃圾回收如何使用循环引用?

2022-08-31 06:47:00

根据我的理解,Java中的垃圾回收会清理一些对象,如果没有其他东西“指向”该对象。

我的问题是,如果我们有这样的东西会发生什么:

class Node {
    public object value;
    public Node next;
    public Node(object o, Node n) { value = 0; next = n;}
}

//...some code
{
    Node a = new Node("a", null), 
         b = new Node("b", a), 
         c = new Node("c", b);
    a.next = c;
} //end of scope
//...other code

a、和应该被垃圾回收,但它们都被其他对象引用。bc

Java垃圾回收如何处理这个问题?(或者它只是一个内存消耗?


答案 1

Java的GC认为,如果对象无法通过从垃圾回收根目录开始的链访问,则将其视为“垃圾”,因此这些对象将被收集。即使物体可能相互指向形成一个循环,但如果它们从根部被切断,它们仍然是垃圾。

有关血腥的细节,请参阅附录 A:Java 平台性能中垃圾回收的真相:策略和战术中有关无法访问的对象的部分。


答案 2

是的,Java垃圾回收器处理循环引用!

How?

有一些特殊对象称为垃圾回收根(GC 根)。这些始终是可访问的,任何在自己的根部具有它们的对象也是如此。

一个简单的 Java 应用程序具有以下 GC 根:

  1. main 方法中的局部变量
  2. 主线程
  3. 主类的静态变量

enter image description here

为了确定哪些对象不再使用,JVM间歇性地运行非常恰当的标记和扫描算法。它的工作原理如下

  1. 该算法遍历所有对象引用(从 GC 根开始),并将找到的每个对象标记为活动对象。
  2. 将回收所有未被标记对象占用的堆内存。它只是被标记为自由的,基本上没有未使用的对象。

因此,如果任何对象无法从GC根目录访问(即使它是自引用或循环引用的),它将受到垃圾回收。

当然,有时如果程序员忘记取消引用对象,这可能会导致内存泄漏。

enter image description here

来源 : Java 内存管理