当前位置: 首页 > 知识库问答 >
问题:

关闭钩子与终结器方法

司徒胤
2023-03-14

我只是不明白为什么一定要使用Runtime.addShutdown Hook。如果你想在jvm退出时做一些清理,为什么不重载守护程序类的finize方法呢?使用关闭钩子比最终确定方法有什么好处。

还有一个不推荐使用的函数runFinalizersOnExit。如果我将其设置为false,我相信终结器不会运行。这与java保证终结器总是在垃圾收集之前运行相矛盾。

共有2个答案

穆俊杰
2023-03-14

关于您的查询

如果您想在jvm退出时进行一些清理,为什么不重载守护进程类的finalize方法呢

我从这篇文章中找到了很好的信息

>

  • 在垃圾收集器回收对象之前调用finalize()。JVM不能保证何时调用此方法。

    finalize()如果对象从finize方法中恢复自身,则GC线程仅调用一次,而finize将不会再次调用。

    在应用程序中,您可能有一些活动对象,这些对象上永远不会调用垃圾收集。

    finalize方法引发的任何异常都被GC线程忽略

    <代码>系统。runFinalization(true)和运行时。getRuntime()。runFinalization(true)方法增加了调用finalize()方法的概率,但现在这两种方法已被弃用。由于缺乏线程安全性和可能的死锁创建,这些方法非常危险。

    返回关闭钩子,根据oracle留档

    public val addShutdown Hook(线程挂钩)注册一个新的虚拟机关闭挂钩。

    Java虚拟机关闭以响应两种事件:

    1. 当最后一个非守护进程线程退出或调用exit(相当于System.exit)方法时,程序正常退出,或
    2. 响应用户中断(如键入^C)或系统范围内的事件(如用户注销或系统关闭),终止虚拟机
    3. 当虚拟机开始其关闭序列时,它将以某种未指定的顺序启动所有注册的关闭挂钩,并让它们同时运行。当所有钩子完成后,如果启用了退出时的终结,那么它将运行所有未调用的终结器
    4. 最后,虚拟机将停止。注意,守护进程线程将在关闭序列期间继续运行,如果通过调用exit方法启动关闭,则非守护进程线程也将继续运行

    但即使是oracle文档也引用了这一点

    关机挂钩也应该很快完成工作。当程序调用exit时,预期虚拟机将立即关闭并退出。

    在极少数情况下,虚拟机可能会中止,即在未完全关闭的情况下停止运行

    考虑到这两种方法的缺点,您应该遵循以下方法

    >

  • 不要依赖于finalize()或关闭挂钩来释放应用程序中的关键资源。

    适当地使用try{}catch{}finally{}块,并释放finally(}块中的关键资源。在释放finally{code>块中的资源时,捕获异常和可丢弃的。

  • 滕璞瑜
    2023-03-14

    不能保证终结器会运行<当垃圾收集对象时,调用code>finalize()。但是,当程序运行时,垃圾收集器可能不会收集任何内容。

    相反,关闭挂钩是在jvm正常退出时运行的。所以即使这也不是百分之百的保证,但它非常接近。只有少数边缘情况下关闭挂钩不会运行。

    编辑我查找了未执行关闭挂钩的边缘情况

    关闭钩子IS执行:

    • 当所有JVM线程都完成执行时
    • 因为对系统的调用。退出()
    • 因为用户点击了CNTRL-C
    • 系统级关闭或用户注销

    未执行关机挂钩:

    • 如果VM由于本机代码中的错误而崩溃,则无法保证挂钩是否会运行
     类似资料:
    • 问题内容: 我只是不明白为什么必须使用Runtime.addShutdownHook。如果要在jvm退出时进行一些清理,为什么不重载daemon类的finalize方法。使用shutdown钩子而不是finalize方法的好处是什么。 还有一个不赞成使用的函数runFinalizersOnExit。如果将其设置为false,我相信终结器将不会运行。这与java保证终结器始终在垃圾回收之前运行是矛盾

    • 主要内容:1 什么是Java 关闭钩子,2 JVM什么时候关闭,3 Java 关闭钩子的语法,4 Java 关闭钩子的例子,5 Java 关闭钩子的例子:匿名类1 什么是Java 关闭钩子 当JVM正常或突然关闭时,shutdown关闭钩子可用于执行清理资源或保存状态。例如:关闭日志文件,发送一些警报或其他内容。因此,如果要在JVM关闭之前执行一些代码,请使用shutdown关闭钩子。 2 JVM什么时候关闭 以下情况,JVM将关闭: 用户在命令提示符下按ctrl + c 调用System.ex

    • 我已经将ShutDownHook添加到我的Spring Boot应用程序中。当我将SIGTERM传递给我的应用程序时,shutdown钩子被触发,但它在中途终止,即在执行过程中终止。谷歌了它,尝试了很多解决方案,但都不起作用。一些专家,请帮我一下。 GracefulShutdownHook类: 我想让关机钩子更新一些缓存和一些逻辑,这会消耗一些额外的处理时间。 当我尝试使用“杀戮-15”杀戮时的日

    • 问题内容: 我在程序中添加了以下代码: 但是,我没有看到该消息。附加信息:我正在Java 7的Netbeans IDE内部运行该程序。 编辑:我忘了补充说,有一个使程序保持活动状态的全局线程。我通过按Netbeans右下角的[x]来关闭它。 问题答案: JVM可以有序或突然关闭。关闭挂钩会运行以有序关闭:当最后一个线程终止时,有人呼叫或通过其他平台特定的方式(例如,按Ctrl-C)。 Shutdo

    • 我如何注册/添加一个自定义的关闭例程,当我的Spring Boot应用程序关闭时,该例程将被触发? 场景:我将Spring Boot应用程序部署到一个Jetty servlet容器(即,没有嵌入式Jetty)。我的应用程序使用Logback进行日志记录,并且我希望在运行时使用Logback的MBean JMX配置器更改日志记录级别。它的文档说明,为了避免内存泄漏,在关机时必须调用特定的Logger

    • 编辑:我忘了加上有一个全局线程使程序保持活力。我通过按Netbeans右下角的[x]来关闭它。