java - 垃圾回收期间何时调用 finalize()?
问题描述
从 :
https://www.baeldung.com/java-memory-management-interview-questions的 Q11
当一个对象符合 GC 条件时,垃圾收集器必须对其运行 finalize();此方法保证只运行一次,因此收集器将对象标记为已完成并让它休息直到下一个周期。
我有几个问题要问:
- 这种说法正确吗?
- 是在标记阶段,垃圾收集器会调用 finalize() 方法吗?
- 为什么它要休息到下一个周期?
PS:我知道 finalize() 最终在 Java 9 中被弃用了。感谢决定这样做的好灵魂。
解决方案
是在标记阶段,垃圾收集器会调用 finalize() 方法吗?
依赖于实现,但通常没有。GC 完成后由后台线程调用终结器。
请记住,GC 可能是一个停止世界的事件,并且应该尽可能短。终结器方法可能很慢,因此不应在 GC 期间调用它们。
为什么它要休息到下一个周期?
在高级(简化)上,它的操作如下(有关术语,请参阅JLS 12.6.1):
GC 检测到无法访问的对象:
如果对象有终结器方法,则将其添加到终结器队列中。
该对象是finalizable。如果该对象可以从一个可终结的对象中访问,则离开它。
该对象是finalizer-reachable。否则现在回收内存。
对象无法访问。
后台终结器线程处理排队的可终结对象:
- 调用
finalize()
方法。
当方法返回时,对象是finalized。
- 调用
由于 GC 已经完成,最终对象正在“休息”直到下一个 GC 周期。
在下一个 GC 循环中,带有 finalizer 方法且标记为finalized的对象被视为不可达,并且内存将被回收(假设 finalizer 方法没有使对象再次可访问)。
请注意,当一个对象是finalizable时,可能会发生许多 GC 周期,即,Finalizer 线程可能需要一段时间来处理该对象。
推荐阅读
- javascript - 在显示主要内容之前将预加载器页面添加到所有页面
- react-admin - 如何使用自定义表单样式
- java - 在什么情况下返回响应比编辑 HttpServletResponse 更好?
- python - 我正在使用套接字在 python 中创建一个多客户端聊天应用程序
- linux - 厨师 cron 作业未运行
- sql - sqlserver上的sql日期时间
- slack - 每三个月的 Slack 提醒
- python-3.x - 沿第 n 行(或整数倍)重新采样 python Pandas
- javascript - 导出图表不保留导航器系列
- html - 如何创建两个彩色的单个 div?