JVM什么时候退出

本文详细解释了Java中守护线程的概念及其作用。守护线程主要用于执行辅助任务,并且不会阻止JVM关闭。当所有非守护线程结束时,即使有守护线程仍在运行,JVM也会终止。

在Java的官方文档中:http://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.1
有如下的描述:
A program terminates all its activity and exits when one of two things happens:
All the threads that are not daemon threads terminate.
Some thread invokes the exit method of class Runtime or class System, and the exit operation is not forbidden by the security manager.

那么问题来了,什么是daemon thread?
请看如下:
Sometimes you want to create a thread that performs some helper function but you don’t want the existence of this thread to prevent the JVM from shutting down.This is what daemon threads are for.
Threads are divided into two types: normal threads and daemon threads. When the JVM starts up, all the threads it creates(such as garbage collector and other housekeeping threads) are daemon threads, except the main thread. When a new thread is created, it inherits the daemon status of the thread that created it, so by default any threads created by the main thread are also normal threads.
Normal threads and daemon threads differ only in what happens when they exit. When a thread exits, the JVM performs an inventory of running threads, and if the only threads that are left are daemon threads,it initiates an orderly shutdown. When the JVM halts, any remaining daemon threads are abandoned finally blocks are not executed, stacks are not unwound the JVM just exits.
Daemon threads should be used sparingly few processing activities can be safely abandoned at any time with no cleanup. In particular, it is dangerous to use daemon threads for tasks that might perform any sort of I/O. Daemon threads are best saved for “housekeeping” tasks, such as a background thread that periodically removes expired entries from an in memory cache.

### JVM正常退出的定义 JVM正常退出是指Java虚拟机在没有发生异常或强制终止的情况下,按照预期完成任务并安全关闭的过程。这种退出方式通常由应用程序主动调用 `System.exit()` 或所有非守护线程执行完毕后触发。正常退出确保了JVM在关闭前能够执行必要的清理操作,例如释放资源、保存状态、关闭连接等,从而避免数据丢失或损坏。 在JVM正常退出时,系统会按照注册顺序依次执行所有已注册的关闭钩子(Shutdown Hooks),这些钩子是通过 `Runtime.getRuntime().addShutdownHook(Thread hook)` 添加的线程任务。关闭钩子机制为应用程序提供了在JVM关闭前执行扫尾工作的机会,例如关闭数据库连接、清理临时文件、释放锁资源等[^3]。 ### JVM正常退出的处理流程 JVM正常退出的处理流程主要包含以下几个阶段: 1. **触发退出条件** JVM正常退出可以通过多种方式触发,例如调用 `System.exit(int status)`、所有非守护线程执行完毕、或通过 `Runtime.halt(int status)` 主动终止JVM。其中,推荐使用 `System.exit(0)` 来主动通知JVM退出,这种方式可以确保关闭钩子的执行。 2. **执行关闭钩子** 在JVM关闭前,会按照注册顺序依次启动所有已注册的关闭钩子。这些钩子通常用于执行清理任务,例如关闭线程池、释放资源、持久化状态等。关闭钩子是并发执行的,因此需要合理设计任务之间的依赖关系和同步机制[^3]。 例如,添加一个关闭钩子来清理临时文件: ```java Runtime.getRuntime().addShutdownHook(new Thread(() -> { System.out.println("执行关闭钩子,清理临时文件..."); // 清理逻辑 })); ``` 3. **资源释放与状态保存** 在关闭钩子执行过程中,应用程序可以完成对关键资源的释放,例如关闭网络连接、释放内存、保存运行状态等。这些操作有助于保证应用在下一次启动时能够正确恢复状态,避免因资源泄漏导致系统异常[^2]。 4. **JVM终止** 所有关闭钩子执行完毕后,JVM会进入终止阶段。此时,JVM会释放所有已分配的资源,并最终退出进程。如果在关闭钩子执行过程中出现异常或死循环,可能导致JVM无法正常退出,因此应确保钩子任务的健壮性和可终止性。 ### 与其他退出方式的对比 - **强制退出** 通过 `kill -9`、`Runtime.halt()`、系统崩溃或断电等方式强制关闭JVM时,JVM不会执行任何关闭钩子,导致资源无法释放、数据丢失等问题。因此,不建议使用此类方式退出JVM[^3]。 - **异常退出** 当JVM遇到未捕获的异常或错误(如 `OutOfMemoryError`)时,也可能导致非正常退出。这种情况下,JVM仍会尝试执行关闭钩子,但执行结果取决于异常的严重程度和钩子任务的健壮性。 ### 总结 JVM正常退出是保障应用程序安全退出的重要机制。通过合理使用关闭钩子和主动调用 `System.exit()`,可以确保在JVM关闭前完成必要的清理任务,从而避免资源泄漏和数据损坏。这种机制在处理临时文件、持久化状态、释放锁等场景中尤为重要。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值