当前位置: 首页 > 面试题库 >

可终结对象如何被回收至少需要2个垃圾回收周期?

狄英哲
2023-03-14
问题内容

我读的这个文章,我真的不能明白
的终结对象(其覆盖的对象是如何finalize法)至少需要2 GC周期可以被回收之前

在可以回收可终结对象之前,至少需要两个垃圾回收周期(最好)。

有人还能详细解释 一个可终结对象如何花费多个GC周期进行回收吗?

我的逻辑观点是,当我们覆盖finalize方法时,运行时将不得不向垃圾收集器注册此对象(以便GC可以调用finalize此对象,这使我认为GC将引用所有finalize对象)。为此,GC将必须牢牢引用可终结对象。如果是这样,那么该对象首先如何成为GC回收的候选对象?这个理论使我感到矛盾。

PS:我知道finalize不推荐使用重写方法,并且从Java 9开始不推荐使用此方法。


问题答案:

没错,垃圾收集器需要引用可终结对象。当然,在确定对象在最终确定之前是否仍可到达时,不得考虑该特定参考。这意味着需要有关该垃圾收集器引用性质的特殊知识。

当垃圾回收器确定某个对象可以进行终结处理时,终结处理程序将运行,这意味着至少在执行终结处理程序之后,该对象才能再次强烈地可访问。完成对象确定后,必须再次变得无法访问该对象,并且必须对其进行检测,然后才能回收该对象的内存。这就是为什么需要至少两个垃圾回收周期的原因。

在广泛使用的热点/
OpenJDK的环境的情况下(在IBM的JVM也有可能),这是通过创建一个特殊的实例来实现,非公子类Reference,一Finalizer,权当一个对象,其类有一个不平凡finalize()方法,已创建。像弱引用和软引用一样,当不存在对引用的强引用时,垃圾收集器会将这些引用排队,但不会清除它们,因此终结器线程可以读取该对象,使其可以再次强烈地到达终结对象。此时,Finalizer已清除,但也不再对其进行引用,因此无论如何它都将像普通对象一样被收集,因此到下一次该引用变得不可访问时,不再存在对其的特殊引用。

对于其类具有“琐碎终结器”的对象(即,被finalize()继承的方法java.lang.Object或空finalize()方法),JVM将采取捷径,而不是首先创建Finalizer实例,因此可以说,这些对象从一开始,大多数对象的行为就好像它们的终结器已经运行一样。



 类似资料:
  • 问题内容: 首先,我想澄清一下我的理解,因为以下问题是相同的。 上面代码的输出是 这意味着,尽管一旦GC运行,实际的对象对象就会被垃圾回收,但是内存中仍然有一个类对象,该对象此时不指向任何对象。 现在考虑到上述理解为真,我对工作原理感到困惑。在下面的代码中 输出: 现在的 问题 是,据说输入是弱引用,这意味着在上面的代码中, 成为实际对象时可以进行垃圾回收,因为不再有对该对象的强引用,但是 和作为

  • 垃圾回收 我们对生产中花了很多时间来调整垃圾回收。垃圾回收的关注点与Java大致相似,尽管一些惯用的Scala代码比起惯用的Java代码会容易产生更多(短暂的)垃圾——函数式风格的副产品。Hotspot的分代垃圾收集通常使这不成问题,因为短暂的(short-lived)垃圾在大多情形下会被有效的释放掉。 在谈GC调优话题前,先看看这个Attila的报告,它阐述了我们在GC方面的一些经验。 Scal

  • 对于开发者来说,JavaScript 的内存管理是自动的、无形的。我们创建的原始值、对象、函数……这一切都会占用内存。 当我们不再需要某个东西时会发生什么?JavaScript 引擎如何发现它并清理它? 可达性(Reachability) JavaScript 中主要的内存管理概念是 可达性。 简而言之,“可达”值是那些以某种方式可访问或可用的值。它们一定是存储在内存中的。 这里列出固有的可达值的

  • 垃圾收集,引用计数,显式分配 和所有的现代语言一样,OCaml提供垃圾收集器,所以你不用像C/C++一样显式地分配和释放内存。 JWZ在他的文章 "Java sucks" rant(Java蛋疼(怒)!): 第一个好家伙是Java没有 free()。其他的都没有所谓了。这几乎掩盖了所有的缺点,不管有多糟糕, 这个有点让后续文档基本都没有意义了,但是...(译注:但是啥大家自己看吧) OCaml的垃

  • 问题内容: 我要求显式垃圾回收器调用。但是窗口并没有从屏幕上消失,为什么垃圾回收器不回收JFrame的对象? 问题答案: 当被创建时,它注册本身在一些内部摇摆的数据结构,其允许它接收到类似的鼠标点击的事件。这意味着在您告诉Swing使用摆脱窗口之前,存在对潜伏在某处的对象的引用。

  • 主要内容:垃圾回收器函数,实例Lua 采用了自动内存管理。 这意味着你不用操心新创建的对象需要的内存如何分配出来, 也不用考虑在对象不再被使用后怎样释放它们所占用的内存。 Lua 运行了一个垃圾收集器来收集所有死对象 (即在 Lua 中不可能再访问到的对象)来完成自动内存管理的工作。 Lua 中所有用到的内存,如:字符串、表、用户数据、函数、线程、 内部结构等,都服从自动管理。 Lua 实现了一个增量标记-扫描收集器。 它使用