【问题标题】:Java not releasing objects with finalize() overrideJava 不释放具有 finalize() 覆盖的对象
【发布时间】:2023-03-12 10:34:01
【问题描述】:

我的应用程序使用了第三方库(JTDS 驱动程序),其中包含一些覆盖 finalize() 方法的对象。我认为他们遵守关于何时不使用finalize() 的所有规则——这不取决于他们是否及时运行或根本不使用。

问题是它们的对象永远不会被释放。他们似乎被困在终结器队列中并且从未被删除。它们在几周内慢慢建立起来,并在堆空间之外运行 JVM。线程转储显示终结器线程只是在等待调用 finalize() 的东西。如果我调用System.runFinalization(),对象将被终结并从终结器队列中正确删除(并且不再出现在堆转储中)。

为什么System.runFinalization() 会正确删除对象,但终结器线程不会自己完成?

【问题讨论】:

  • 我看不出有人如何重现您的问题以帮助您。
  • 你在启动时向 JVM 传递了哪些参数?
  • 除非你有这些 finalize 方法的代码可用,否则你怎么指望有人帮忙呢?
  • 我真的只是希望有人对 Finalizer 的一般行为发表评论,而不一定要重现该问题。也许有人在他们的类(或者在我的情况下是第三方类)中看到了类似的问题,这些类覆盖了 finalize()。
  • 描述终结器的行为实际上非常简单:“不可预测”;) 你真的应该向库作者报告这个错误

标签: java garbage-collection finalizer


【解决方案1】:

今天遇到了同样的问题。您没有指定您正在使用的 JVM,但以防万一它是 OpenJDK - 有一个错误 https://lists.launchpad.net/openjdk/msg10021.html 他们说它已经修复了,所以你只需要升级。

【讨论】:

    【解决方案2】:

    这意味着您的 finalize() 方法花费的时间太长,导致对象在队列中堆积等待被调用。

    对象在被调用时从队列中移除,并且在被调用后不会在队列中。

    【讨论】:

    • 但是线程转储显示终结器线程只是在等待,没有参与运行终结方法之一?在调用 runFinalization 时,听起来终结器都及时运行?
    • @GrahamGriffiths 问题很可能不是它看起来的那样。注意:所有对象都完成后,必须调用 GC 来清理它们。
    • 好吧,@GrahamGriffiths,终结器线程在任何时候都没有做任何事情,我可以在线程转储中捕获它。
    • @Jason 该评论是为你准备的。你真的知道终结器线程运行后终结器队列不为空吗?仅仅剩下很多终结器节点并不意味着仍然使用其中的任何一个。
    • 如前所述,终结器线程在任何线程转储期间都没有运行 finalize(),对象会在几周内累积,并且调用 System.runFinalization() 将清理不到一秒钟的时间。看起来终结器线程无法跟上被丢弃的对象。
    【解决方案3】:

    为什么终结器线程不删除这些对象?

    简单的答案是,终结器内部的某些东西导致了死锁。终结器是最糟糕的清理方法。它由垃圾收集器调用。

    垃圾回收时由对象上的垃圾回收器调用 确定不再有对该对象的引用。 当要成为垃圾收集器的对象具有强引用时会发生什么?该对象永远不会获得垃圾收集器。我强烈怀疑这就是你的情况。

    Joshua Bloch 在 Effective Java 中说:

    总的来说,不要使用终结器,除非作为安全网或终止 非关键原生资源

    避免使用终结器 - 终结器是不可预测的,通常很危险,而且通常是不必要的

    http://www.informit.com/articles/article.aspx?p=1216151&seqNum=7

    【讨论】:

    • 终结器线程没有死锁。它只是在等待有事可做。并且库的作者确实正确地使用了 finalize() 方法作为“安全网或终止非关键资源”。事实上,finalize() 方法要关闭的所有东西都已经关闭了。只是这个类重写了 finalize() 导致它被添加到终结器队列中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-04
    • 1970-01-01
    • 2014-04-28
    • 1970-01-01
    • 1970-01-01
    • 2013-08-15
    • 1970-01-01
    相关资源
    最近更新 更多