0%

JVM生命周期

JVM 生命周期:从启动到退出的完整历程

JVM(Java 虚拟机)作为运行字节码的虚拟进程,其生命周期遵循 “启动 - 执行 - 退出” 的完整流程。理解这一过程有助于深入掌握 JVM 的运行机制,以及排查与进程生命周期相关的问题(如进程异常退出、资源未释放等)。

JVM 启动:初始化与类加载

JVM 的启动是一个从无到有创建虚拟机进程的过程,核心是通过引导类加载器加载初始类,完成虚拟机的初始化。

1. 启动触发方式

  • 命令行启动:通过java命令启动(如java -jar app.jarjava com.example.Main),底层调用 JVM 的启动接口(如JNI_CreateJavaVM)。
  • 嵌入式启动:通过 JNI(Java Native Interface)在其他语言(如 C/C++)中嵌入 JVM,手动调用启动接口创建虚拟机实例。

2. 启动核心步骤

  1. 创建 JVM 实例:操作系统分配进程资源,初始化 JVM 的内部数据结构(如内存管理模块、线程管理模块)。
  2. 初始化引导类加载器:引导类加载器(Bootstrap ClassLoader)是 JVM 自带的加载器,负责加载 JVM 运行必需的核心类(如java.lang.Objectjava.lang.ClassLoader等,位于rt.jar中)。
  3. 加载初始类
    初始类由虚拟机实现指定(通常是用户程序的入口类,即包含main方法的类)。引导类加载器通过类的全限定名找到并加载该类,触发类加载的 “加载 - 链接 - 初始化” 流程(见前文)。
  4. 启动主线程:初始化完成后,JVM 创建主线程(main线程),执行初始类的main方法,标志着程序开始执行。

3. 启动阶段的关键特点

  • 启动过程依赖 JVM 的配置参数(如堆大小-Xms、垃圾回收器-XX:+UseG1GC等),这些参数会影响内存分配、执行引擎等核心组件的初始化。
  • 若初始类加载失败(如类不存在、字节码损坏),JVM 会在启动阶段抛出错误并终止。

JVM 执行:运行 Java 程序

JVM 启动后进入执行阶段,其核心任务是运行 Java 程序(字节码),直到程序结束或异常终止。

1. 执行阶段的核心行为

  • 线程管理:JVM 会创建和管理多个线程(如主线程、GC 线程、守护线程等),线程的生命周期与 JVM 进程绑定。
  • 内存管理:
    • 动态分配对象内存(主要在堆中);
    • 垃圾回收器定期回收不可达对象的内存,避免内存泄漏。
  • 字节码执行:通过解释器和 JIT 编译器协同执行字节码,热点代码会被编译为机器码以提升效率。
  • 异常处理:当程序抛出未捕获的异常时,JVM 会终止对应的线程;若主线程异常终止,可能导致 JVM 退出。

2. 执行阶段的生命周期特征

  • JVM 进程的生命周期与程序的生命周期一致:程序运行时 JVM 持续运行,程序结束后 JVM 退出。
  • 执行过程中,JVM 通过 JMX(Java Management Extensions)等接口提供运行时监控能力(如查看内存使用、线程状态等)。

JVM 退出:终止进程与释放资源

JVM 退出意味着虚拟机进程终止,所有资源(内存、文件句柄、线程等)会被释放。JVM 退出的触发方式可分为正常退出异常退出两类。

1. 正常退出

程序正常执行完毕,JVM 主动终止进程,常见场景:

  • 程序执行完成main方法执行结束,主线程退出,且没有其他非守护线程运行(JVM 会等待所有非守护线程结束后退出)。
  • 主动调用退出方法:
    • 调用System.exit(int status)Runtime.getRuntime().exit(int status):终止 JVM,status为退出状态码(0 表示正常,非 0 表示异常)。
    • 调用Runtime.getRuntime().halt(int status):强制终止 JVM,不执行退出钩子(shutdown hook),直接终止进程。

2. 异常退出

因错误或外部干预导致 JVM 被迫终止,常见场景:

  • 未捕获的异常 / 错误:线程抛出未捕获的Error(如OutOfMemoryError)或RuntimeException,导致线程终止;若所有非守护线程终止,JVM 退出。
  • 操作系统干预:
    • 外部进程发送终止信号(如kill -9 <pid>在 Linux 中强制杀死 JVM 进程)。
    • 操作系统崩溃或断电,导致 JVM 进程异常终止。
  • JNI 调用错误:通过 JNI 调用的本地方法执行错误(如访问非法内存),可能导致 JVM 崩溃。

3. 退出前的清理动作

JVM 正常退出前会执行一系列清理操作:

  • 执行退出钩子(Shutdown Hooks):通过Runtime.getRuntime().addShutdownHook(Thread hook)注册的线程会在 JVM 退出前执行,用于释放资源(如关闭文件、断开数据库连接等)。
  • Finalizer 机制:部分对象的finalize()方法可能被执行(但不保证一定执行,不建议依赖)。
  • 释放资源:JVM 释放分配的内存、关闭文件句柄、终止所有线程等,最终操作系统回收进程资源。

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10