Java垃圾回收如何处理循环引用?
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
a
、b
和c
应该被垃圾回收,但它们都被其他对象引用了。
Java垃圾回收如何处理这种情况?(还是只是内存泄漏?)
admin 更改状态以发布 2023年5月24日
是的,Java垃圾收集器可以处理循环引用!
How?
有一些特殊的对象被称为垃圾回收根(GC roots)。这些对象总是可达的,因此任何拥有它们作为自己根的对象也是可达的。
一个简单的Java应用程序有以下GC roots:
- main方法中的局部变量
- 主线程
- 主类的静态变量
为了确定哪些对象不再使用,JVM间歇性地运行了一个非常恰当称为标记-清除算法的算法。它的工作原理如下:
- 算法遍历所有对象引用,从GC roots开始,并将找到的每个对象标记为活动对象。
- 回收所有未被标记的堆内存。它被简单地标记为可用的内存,基本上被清除未使用的对象。
因此,如果任何对象不可从GC roots访问(即使是自引用或循环引用),它都将被回收。
当然,如果程序员忘记取消引用对象,有时可能会导致内存泄漏。
来源:Java内存管理