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

31 浏览
0 Comments

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

据我所知,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

abc应该被垃圾回收,但它们都被其他对象引用了。

Java垃圾回收如何处理这种情况?(还是只是内存泄漏?)

admin 更改状态以发布 2023年5月24日
0
0 Comments

是的,Java垃圾收集器可以处理循环引用!

How?

有一些特殊的对象被称为垃圾回收根(GC roots)。这些对象总是可达的,因此任何拥有它们作为自己根的对象也是可达的。

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

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

enter image description here

为了确定哪些对象不再使用,JVM间歇性地运行了一个非常恰当称为标记-清除算法的算法。它的工作原理如下:

  1. 算法遍历所有对象引用,从GC roots开始,并将找到的每个对象标记为活动对象。
  2. 回收所有未被标记的堆内存。它被简单地标记为可用的内存,基本上被清除未使用的对象。

因此,如果任何对象不可从GC roots访问(即使是自引用或循环引用),它都将被回收。

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

enter image description here

来源:Java内存管理

0
0 Comments

Java的垃圾回收将对象视为“垃圾”,如果它们不通过从垃圾回收根开始的链路可达,则这些对象将被收集。即使对象互相指向形成一个循环,如果它们与根断开连接,它们仍然是垃圾。

有关不可达对象的部分,请参见附录A:《Java平台性能:策略和战术》中的《垃圾回收的真相》章节,了解更多详细信息。

0