解读JVM的生命周期是怎么样的

 更新时间:2025年03月10日 09:01:00   作者:冰糖心书房  
JVM的生命周期包括启动、运行和终止三个阶段,启动阶段包括创建JVM实例、加载和初始化核心类库、加载main方法所在的类和初始化类,运行阶段包括执行main方法、类加载、字节码执行、内存管理、线程管理和异常处理,终止阶段包括正常终止、异常终止和外部终止

JVM的生命周期是怎么样的

JVM 的生命周期是指 JVM 实例从启动到终止的整个过程。

一个 Java 应用程序通常对应一个 JVM 实例(除非使用 JNI 等技术在同一进程中创建多个 JVM 实例,但这并不常见)。

JVM 的生命周期阶段

启动 (Startup)

  • 创建 JVM 实例: 当你使用 java 命令运行 Java 程序时,操作系统会创建一个新的进程,并在该进程中启动一个 JVM 实例。
  • 加载和初始化:
    • 查找并加载 JDK: 找到 JRE (Java Runtime Environment) 的位置.
    • 创建引导类加载器 (Bootstrap Class Loader): 加载核心类库(rt.jar 等)。
    • 创建扩展类加载器 (Extension Class Loader) 和应用程序类加载器 (Application Class Loader): 分别加载扩展类库和应用程序的类。
    • 加载 main 方法所在的类: 使用应用程序类加载器加载包含 main 方法的类。
    • 初始化类: 执行类的静态初始化块和静态变量赋值。
  • 命令行参数: 解析传入java命令的参数.

运行 (Execution)

  • 执行 main 方法: JVM 调用 main 方法,开始执行 Java 程序。
  • 类加载: 在程序运行过程中,根据需要动态加载类。
  • 字节码执行: JVM 的执行引擎解释或编译执行字节码。
  • 内存管理: JVM 分配和管理内存,进行垃圾回收。
  • 线程管理: JVM 创建和管理线程。
  • 异常处理: JVM 处理程序中发生的异常。

终止 (Termination)

正常终止:

  • 当程序执行完 main 方法,并且所有非守护线程(non-daemon threads)都已结束时,JVM 正常终止。
  • 可以通过调用 System.exit(status) 方法显式终止 JVM。status 是退出状态码(0 表示正常退出,非 0 表示异常退出)。

异常终止:

  • 如果程序中发生了未捕获的异常,并且没有设置默认的未捕获异常处理器,JVM 会异常终止。
  • 可以通过 Thread.setDefaultUncaughtExceptionHandler() 设置默认的未捕获异常处理器。

外部终止:

  • 用户可以通过操作系统命令(例如,在 Linux 中使用 kill 命令)强制终止 JVM 进程。
  • JVM 可能会收到操作系统发送的终止信号(例如,SIGTERM)。

钩子 (Shutdown Hooks):

  • 在 JVM 终止之前,可以注册一些钩子函数(shutdown hooks),用于执行一些清理操作(例如,关闭数据库连接、释放资源等)。
  • 可以使用 Runtime.getRuntime().addShutdownHook(Thread hook) 方法注册钩子函数。
  • 钩子函数会在以下情况下执行:
    • 程序正常退出。
    • 调用 System.exit()
    • 用户中断程序(例如,按下 Ctrl+C)。
    • 系统关闭。
  • 钩子函数执行的顺序是不确定的。

总结流程图

+----------------+
|    启动 JVM     |  (java 命令)
+----------------+
        |
        V
+----------------+
|  加载和初始化    |
|  - 查找并加载 JDK |
|  - 创建类加载器   |
|  - 加载 main 类   |
|  - 初始化类      |
+----------------+
        |
        V
+----------------+
|    运行程序     |
|  - 执行 main 方法|
|  - 类加载       |
|  - 字节码执行    |
|  - 内存管理     |
|  - 线程管理     |
|  - 异常处理     |
+----------------+
        |
        V
+----------------+
|    终止 JVM     |
|  - 正常终止      |
|  - 异常终止      |
|  - 外部终止      |
|  - 执行钩子函数   |
+----------------+

代码示例 (演示钩子函数)

public class JVMLifecycle {

    public static void main(String[] args) {

        // 注册钩子函数
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            System.out.println("JVM 即将终止,执行清理操作...");
            // 在这里执行清理操作 (例如,关闭数据库连接、释放资源等)
        }));

        System.out.println("程序开始执行...");

        // 模拟程序运行一段时间
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("程序执行完毕...");

        // 可以选择显式退出 (也可以不调用 exit,让程序自然结束)
        // System.exit(0);
    }
}

运行结果:

程序开始执行...
程序执行完毕...
JVM 即将终止,执行清理操作...

注意:

  • 如果程序中存在死循环或无限等待,JVM 可能永远不会终止。
  • 守护线程 (daemon thread) 不会阻止 JVM 终止。当所有非守护线程都结束后,JVM 会强制终止所有守护线程。
  • 钩子函数应该尽量简短,避免执行耗时的操作,否则可能会导致 JVM 无法正常终止。
  • 不要在钩子函数中调用 System.exit(),否则会导致死循环。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 使用Spring @DependsOn控制bean加载顺序的实例

    使用Spring @DependsOn控制bean加载顺序的实例

    这篇文章主要介绍了使用Spring @DependsOn控制bean加载顺序的实例讲解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Spring使用@Autowired为抽象父类注入依赖代码实例

    Spring使用@Autowired为抽象父类注入依赖代码实例

    这篇文章主要介绍了Spring使用@Autowired为抽象父类注入依赖代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • SpringBoot 动态配置Profile环境的方式

    SpringBoot 动态配置Profile环境的方式

    这篇文章主要介绍了SpringBoot 动态配置Profile环境的方式,本文通过图文实例相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-10-10
  • MybatisPlus BaseMapper 中的方法全部 Invalid bound statement (not found Error处理)

    MybatisPlus BaseMapper 中的方法全部 Invalid bound statement (not f

    这篇文章主要介绍了MybatisPlus BaseMapper 中的方法全部 Invalid bound statement (not found)的Error处理方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • 小白也可以学会的Java NIO的Write事件

    小白也可以学会的Java NIO的Write事件

    刚开始对NIO的写操作理解的不深,不知道为什么要注册写事件,何时注册写事件,为什么写完之后要取消注册写事件,今天特地整理了本篇文章,需要的朋友可以参考下
    2021-06-06
  • mysql数据库忘记密码时如何修改

    mysql数据库忘记密码时如何修改

    本文主要介绍了mysql数据库忘记密码时如何修改的步骤方法,具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • Java使用OpenCV实现实时对象追踪的代码示例

    Java使用OpenCV实现实时对象追踪的代码示例

    视觉跟踪是指通过分析视频帧来自动追踪一个或多个移动对象的过程,这项技术广泛应用于监控、人机交互、增强现实和自动驾驶等领域,本文给大家介绍了Java如何使用OpenCV实现实时对象追踪,需要的朋友可以参考下
    2025-09-09
  • springboot2.x整合shiro权限框架的使用

    springboot2.x整合shiro权限框架的使用

    这篇文章主要介绍了springboot2.x整合shiro权限框架的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • java+SpringBoot设计实现评教系统

    java+SpringBoot设计实现评教系统

    这篇文章主要介绍了用过Java SpringBoot实现一个简单的评价系统,可以做到学生管理、教师管理、评教管理、指标管理、课程管理等。感兴趣的可以了解一下
    2021-12-12
  • 详解Java读取本地文件并显示在JSP文件中

    详解Java读取本地文件并显示在JSP文件中

    这篇文章主要介绍了详解Java读取本地文件并显示在JSP文件中的相关资料,这里提供实例帮助大家实现这样的功能,希望能帮助到大家,需要的朋友可以参考下
    2017-08-08

最新评论