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

标签 java garbage-collection heap-memory g1gc finalize

这个问题在这里已经有了答案:





How does Java GC call finalize() method?

(4 个回答)



How finalizable objects takes at least 2 garbage collection cycles before it can be reclaimed?

(2 个回答)



why allocation phase can be increased if we override finalize method?

(1 个回答)


去年关闭。




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

最佳答案

是的,一个 GC跟踪所有这些对象及其类型。
事实上,GC 有一个专门的阶段来处理这些特殊的引用:WeakReference , SoftReference , PhantomReference和人工 Finalizer s。有人称之为 Cleanup phase , 一些 Reference Processing ;作为其中的一部分,有 Pre-cleapupPost-cleanup阶段。
但想法是,当 GC在标记阶段遇到这样一个“特殊”的引用,它会关注这些。首先,它分别跟踪它们(想想:在特殊的 List 中注册它们)。当标记阶段完成时(至少在一些 GC 秒),它会在暂停(stop-the-world)下分析这些引用。其中一些使用起来并不复杂:WeakReference s 和 SoftReference s 是最简单的:如果 referent弱/软可达,回收它并向 ReferenceQueue 发送一个特殊事件. PhantomReference s 几乎相同(java-8 和 9 之间存在差异,但不会详细介绍)。

... where Java needs to call finalize() on the dead objects


你就在这里。最丑的是Finalizers ,主要是因为GC必须复活它得到的死亡对象,因为它需要调用 finalize在一个实例上并且该实例无法访问或已死;但 GC 无法回收它。所以一个 GC首先恢复对象,只是在下一个将在此实例上工作的循环中立即杀死它。不一定是第二个,一般可以是第 100 个周期;但它必须是涉及这个特定实例的第二个。

关于java - 如果 Java 的分代垃圾收集器遍历 Activity 对象图,它们如何知道要对哪些对象调用 finalize()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59992402/

相关文章:

java - Liferay portlet 可以获取参数吗?

java - Swing 线程安全编程

Java:读取CSV文件以获取各种统计数据的最小值、最大值、平均值

.net - 如何模拟此应用程序挂起方案?

java - Maven 部署插件

java - 如何比较行并在java中找到常见值和不常见值(使用逗号)

garbage-collection - D 垃圾收集器 - 估计运行频率和运行时长?

java - 线程 "main"java.lang.OutOfMemoryError : GC overhead limit exceeded 中 POI 的异常

c - 为c中的结构分配内存

android - 管理堆大小