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垃圾收集如何处理这个问题? (或者它只是一个内存泄漏?)


Java的GC将对象视为“垃圾”,如果它们无法通过从垃圾收集根开始的链来访问,则会收集这些对象。 即使对象可能指向对方形成一个循环,但如果它们从根部切断,它们仍然是垃圾。

附录A:有关Java平台性能:策略和策略中垃圾收集的真相,请参阅关于不可达对象的部分。


是的Java垃圾收集器处理循环参考!

How?

有一些称为垃圾收集根(GC根)的特殊对象。 这些都是可以访问的,任何对象都有自己的根。

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

  • 主要方法中的局部变量
  • 主线程
  • 主类的静态变量
  • 在这里输入图像描述

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

  • 该算法遍历所有对象引用,从GC根开始,并标记每个找到的对象。
  • 所有未被标记对象占用的堆内存都将被回收。 它被简单地标记为空闲的,基本上没有未使用的对象。
  • 因此,如果有任何对象无法从GC根访问(即使它是自引用的或循环引用的),它将受到垃圾回收。

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

    在这里输入图像描述

    来源:Java内存管理


    垃圾收集器从一些始终被认为“可达”的“根”集合开始,例如CPU寄存器,堆栈和全局变量。 它的工作原理是找到这些区域中的任何指针,并递归查找它们指向的所有内容。 一旦发现这一切,其他一切都是垃圾。

    当然,有很多变化,主要是为了速度。 例如,大多数现代垃圾收集器都是“代数”的,意思是它们将物体分成几代,随着物体变旧,垃圾收集器在两次尝试确定该物体是否仍然有效的时间间隔越来越长 - 它只是开始假设,如果它活了很长时间,它会继续活得更长久的机会是相当不错的。

    尽管如此,基本思想仍然是一样的:它都基于从一些根本理所当然的东西开始,然后追踪所有的指针,找出还有什么可以使用的东西。

    有趣的是:人们通常会对垃圾收集器的这部分与用于诸如远程过程调用之类的用于封送对象的代码之间的相似程度相似程度感到惊讶。 在每种情况下,你都是从一些根对象开始,然后追着指针找到所有其他的对象,

    链接地址: http://www.djcxy.com/p/27153.html

    上一篇: How does Java Garbage Collection work with Circular References?

    下一篇: Garbage collection Libraries in C++