JVM的生命周期

1.加载(Loading):

在加载阶段,JVM会找到并加载Java字节码文件。加载阶段分为三个步骤:通过类的全限定名找到对应的字节码文件,创建一个与该类相关的Class对象,将类的静态数据结构存储在方法区中。加载完成后,JVM内存中就存在了一个Class对象,它包含了该类的所有属性和方法的信息。

2.验证(Verification):

验证阶段是确保加载的字节码文件符合JVM规范的过程。在验证阶段,JVM会检查字节码的格式、语义以及符号引用的正确性,以防止安全漏洞和运行时错误。验证的目标包括:类文件结构的完整性、语义的正确性和符号引用的验证。

3.准备(Preparation):

在准备阶段,JVM会为类的静态变量分配内存并设置默认初始值。这些静态变量包括基本数据类型和引用类型,它们会被初始化为零值(零值是每种数据类型的默认值,如0、false、null等),而不是类中定义的初始值。此阶段会在方法区中为每个静态变量分配内存空间。

4.解析(Resolution):

解析阶段是将符号引用转换为直接引用的过程。在Java中,类的方法和字段访问采用的是符号引用,而不是直接引用。解析阶段会将这些符号引用转化为直接引用,以便能够正确访问和调用类的方法和字段。解析阶段包括类、字段和方法的解析。

5.初始化(Initialization):

初始化阶段是JVM执行类的初始化代码的过程。类的初始化代码包括静态变量的赋值和静态代码块的执行。在该阶段,JVM会按照类的加载顺序依次初始化每个类,确保所有的静态变量被正确初始化,并执行静态代码块中的代码。初始化阶段是类加载过程的最后一步。

6.使用(Usage):

使用阶段是指JVM执行Java程序的过程。在使用阶段,JVM会按照程序的流程执行相应的指令,并处理方法调用和对象创建等操作。JVM通过执行Java字节码来实际运行程序,包括调用方法、访问字段和创建对象等操作。

7.卸载(Unloading):

卸载阶段是指JVM从内存中卸载不再被使用的类和相关资源。当一个类不再被引用,并且没有正在执行的对象实例时,JVM会卸载该类,并释放其占用的内存空间。卸载过程由垃圾回收器完成,它会检测并回收不再被引用的类和对象。

JVM的生命周期是一个动态的过程,它负责加载、验证、准备、解析、初始化、使用和卸载Java字节码文件。每个阶段都有特定的任务和目标,保证程序能够正确运行并在不再需要时释放资源。

Java虚拟机(JVM)的启动和执行过程分为以下几个步骤:

  1. 加载:JVM首先加载JDK的核心类库以及应用程序所需的其他类。加载过程中包括以下几种方式:

    • 类文件加载:将编译后的Java类文件加载到内存中。
    • 字节码校验:验证加载的字节码是否符合Java语法规范。
    • 字节码转换:将字节码转换成机器码,以便于执行。
  2. 链接:在加载完类文件后,JVM需要进行链接处理,包括以下三个阶段:

    • 验证:检查字节码是否符合JVM规范。
    • 准备:为类变量(静态变量)分配内存空间,并设置默认初始值。
    • 解析:将符号引用转换为直接引用。
  3. 初始化:执行类的初始化代码,包括静态变量的赋值和静态代码块的执行。JVM保证类的初始化在多线程环境下的安全性。

  4. 执行:将字节码转换为机器码,逐行执行机器码指令。执行过程中需要注意以下几点:

    • 进行即时编译(Just-In-Time Compilation):将热点代码(被频繁调用的代码)编译成机器码,以提高执行效率。
    • 垃圾回收(Garbage Collection):在执行过程中,JVM会自动回收不再使用的内存空间,以确保内存的有效利用。
  5. 销毁:当Java程序执行完毕或者出现异常时,JVM会释放所有占用的资源,并终止执行。

JVM的启动和执行流程可以总结为:加载类文件、链接处理、初始化类、执行字节码。通过这一流程,JVM能够实现Java程序的跨平台运行,并提供内存管理和垃圾回收等功能,以确保程序的安全和性能。

JVM(Java Virtual Machine)的退出流程可以分为正常退出和非正常退出两种情况。

  1. 正常退出:

    • JVM收到终止请求,如通过调用System.exit()方法或者通过kill命令结束进程。
    • JVM开始执行退出过程,首先会执行已注册的关闭钩子(Shutdown Hook)。
    • 关闭钩子是一段在JVM正常退出之前执行的代码,可以通过Runtime.addShutdownHook方法注册。
    • JVM的关闭钩子可以用于释放资源、保存状态等操作。
    • 在关闭钩子执行完毕后,JVM执行一些清理操作,如垃圾回收、关闭网络连接等。
    • 最后,JVM完全终止运行,进程退出。
  2. 非正常退出:

    • JVM遇到致命错误,如OutOfMemoryError或StackOverflowError。
    • JVM无法继续执行,并抛出一个异常。
    • 异常的抛出会导致程序所在的线程被终止,然后整个JVM进程退出。

JVM的退出过程可以通过实现一个Shutdown Hook来观察,示例代码如下:

java 复制代码
public class ShutdownHookExample {
    public static void main(String[] args) {
        // 注册一个关闭钩子
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                System.out.println("Shutting down...");
            }
        });

        // 模拟程序运行
        try {
            Thread.sleep(5000); // 程序休眠5秒钟
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 手动触发退出事件
        System.exit(0);
    }
}

该示例程序在运行时注册了一个关闭钩子,并在关闭钩子中打印一条消息。然后程序会休眠5秒钟,之后手动调用System.exit(0)方法触发JVM退出事件。在程序运行时,我们可以观察到在5秒后打印的"Shutting down..."消息,表示关闭钩子被执行。然后JVM会继续执行清理操作并退出。

需要注意的是,关闭钩子的执行顺序是不确定的,不同的钩子可能在不同的线程中执行。因此,如果有多个关闭钩子,它们之间应该是独立的,不依赖于其他钩子的执行顺序。

相关推荐
1.01^100011 小时前
[5-01-01].第04节:初识字节码文件 - 字节码文件作用
jvm
找不到、了14 小时前
JVM核心知识整理《1》
jvm
L.EscaRC16 小时前
面向 Spring Boot 的 JVM 深度解析
jvm·spring boot·后端
学到头秃的suhian1 天前
JVM-类加载机制
java·jvm
NEFU AB-IN2 天前
Prompt Gen Desktop 管理和迭代你的 Prompt!
java·jvm·prompt
唐古乌梁海2 天前
【Java】JVM 内存区域划分
java·开发语言·jvm
众俗2 天前
JVM整理
jvm
echoyu.2 天前
java源代码、字节码、jvm、jit、aot的关系
java·开发语言·jvm·八股
代码栈上的思考3 天前
JVM中内存管理的策略
java·jvm
thginWalker3 天前
深入浅出 Java 虚拟机之进阶部分
jvm