【问题标题】:What triggers the java Garbage Collector什么触发了 java 垃圾收集器
【发布时间】:2013-01-11 13:03:13
【问题描述】:

我对 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 有循环引用。

但是节点 a 呢?会被垃圾回收吗?

节点 b 是否有外部实时引用会有所不同吗?假设如果节点 b 从不同的地方引用它,那会让节点 a 留在内存中吗?

【问题讨论】:

  • 可以收集任何没有来自线程根的 strong 引用的对象。这意味着两个对象可以相互引用但将被收集。您可以对对象进行弱引用,但仍可以对其进行清理。

标签: java garbage-collection jvm


【解决方案1】:

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

节点 a 没有任何指向它的引用。因此,即使它指的是活动对象,它也符合 gc 条件。由于节点 b 有实时引用,它不会被 gc'ed。

【讨论】:

【解决方案2】:

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

基本上,每个没有实时引用的对象都会被收集。这些对象中包含的任何对象都将遵循相同的机制,如果没有其他对它们的引用,它们也将被垃圾回收。如果有来自其他对象的实时引用,它们将保留。

【讨论】:

    【解决方案3】:

    GC 知道哪些对象是活动的,因为它将所有活动对象复制到一个新的内存区域,并且所有未复制的对象都将在下一次被覆盖。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-03
      • 2012-03-21
      • 2015-04-10
      • 1970-01-01
      • 2011-11-07
      • 2013-12-03
      相关资源
      最近更新 更多