如果 Java 的分代垃圾收集器遍历活动对象图,它们如何知道要对哪些对象调用 finalize()?

use*_*368 5 java garbage-collection heap-memory finalize g1gc

我的理解是像 ParallelGC 和 G1 这样的 GC 是“分代”收集器。垃圾收集几乎是作为副产品发生的,因为您将所有活动对象移动到新的堆区域,而旧区域中剩余的任何内容都将被简单地覆盖。这种“副产品”的解释很有意义,除了 Java 需要在死对象上调用 finalize() 的部分。Java 是否还保留每个堆区域中所有对象的单独列表,以便与活动对象进行比较?

Wor*_*ess 2

Java 是否还保留每个堆区域中所有对象的单独列表,以便与活动对象进行比较?

想一想 -> 一个堆中所有对象的列表,你在哪里可以找到这样的东西?答案非常简单明了,你可以在堆中找到所有对象的地方就是堆。

垃圾收集几乎是作为副产品发生的,因为您将所有活动对象移动到新的堆区域,并且旧区域中剩余的任何内容都将被覆盖。这个“副产品”解释很有意义,除了 Java 需要对死对象调用 Finalize() 的部分。

为什么这会成为一个问题呢?正如您正确指出的那样,所有活动对象都正在被处理(要么移动到下一个堆空间,要么老化)。在垃圾收集期间(次要和主要垃圾收集),您正在检查已处理堆空间中所有对象的引用(在检查之前您不知道哪些是活的/死的),这意味着您确切地知道哪些是活的,哪些是活的之后就死了 -> 什么阻止你为死对象调用 Finalize() ?您可以直接从堆访问它们,这样您就可以做到这一点。

另外,作为更详细地解释垃圾收集的资源,我仍然发现Java 垃圾收集基础知识非常好,特别是考虑到它的分代垃圾收集的逐步示例。

  • 该列表是[就在这里](http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/lang/ref/Finalizer.java#l34), `static Finalizer unfinalized;` 字段指向第一个节点,`private Finalizer next, prev;` 字段构建链表。但它只包含类实际上声明了`finalize()`方法的对象(`Finalizer`本身没有这样的方法,并且`java.lang.Object`的空方法不算在内,否则,这不能工作)。 (2认同)