2013-01-11 106 views
0

我对Java中垃圾收集的工作方式有点困惑。什么触发java垃圾收集器

我得到一个对象有资格进行垃圾回收时没有更多的实时引用,但如果它有活动对象的引用呢?

可以说我有节点的集合,再次引用多个节点

List 
1 -> Node a -> Node b 
2 -> Node c -> Node d 
3 -> Node d -> Node c 
4 -> Node e 
5 

现在,如果我删除列表,节点C d和e应该被垃圾收集。节点e不再有对它的引用,并且节点c和d具有循环引用。

但是Node a呢?它会被垃圾收集?

无论节点b是否有外部活动引用,它会不同吗?说如果节点b从一个不同的地方引用它,这会使节点停留在内存中吗?

+1

可以收集任何没有来自线程根的强*参考的对象。这意味着两个对象可以相互引用,但会被收集。你可以对对象有一个弱引用,但它仍然可以被清理。 –

回答

4

存在引用的根集(当前局部变量,静态引用,堆栈帧的操作数堆栈),这被认为是实时的。任何无法从此根引用集访问的内容都有资格进行垃圾回收。

节点a没有任何引用指向它。因此,即使它指的是一个活动对象,它也有资格使用gc。由于节点b具有实时参考,因此它不会被gc化。

+1

我推荐Brian Goetz撰写的这两篇优秀文章:[垃圾收集简史](http://www.ibm.com/developerworks/java/library/j-jtp10283/)和[HotSpot JVM垃圾收集] (http://www.ibm.com/developerworks/java/library/j-jtp11253/)。 –

0

GC知道哪些对象处于活动状态,因为它会将所有活动对象复制到新的内存区域,下次所有未复制的对象都将被覆盖。

请注意,这对于Oracle VM中GC的当前实现有效。其他虚拟机可以以另一种方式处理它。

2

如果节点B有其他任何对它的引用,那么对于节点A的垃圾收集无关紧要。如果节点A没有对它的引用,它将被垃圾回收。节点B将保留,因为它仍然有实时参考。

基本上,没有实时引用它的每个对象都将被收集。包含在这些对象中的任何对象都将受到同样的机制,如果没有其他引用,它们也将被垃圾收集。如果有其他对象的实时引用,它们将保留。