jvm运行流程

Java虚拟机(JVM)是运行Java字节码的虚拟机。JVM的运行流程可以分为几个阶段:加载(Loading)、链接(Linking)、初始化(Initialization)、使用(Using)和卸载(Unloading)。JVM运行时,主要通过类加载器(ClassLoader)、执行引擎(Execution Engine)以及内存区域(Memory Areas)协同工作来完成任务。

类加载(Class Loading)

JVM 启动时,主类(带有 main 方法的类)会被加载。JVM 使用了不同级别的类加载器:

  1. 引导类加载器(Bootstrap Class Loader):用原生代码实现,加载 JVM 基础核心类库。
  2. 扩展类加载器(Extension Class Loader) :加载扩展库(jre/lib/ext 或者 Java 系统变量 java.ext.dirs 指定的目录中的 JAR 包)。
  3. 系统类加载器(System/Application Class Loader) :加载系统类路径(classpath)上的类库。

在 OpenJDK 源码中,这部分对应的是 ClassLoader 类和 sun.misc.Launcher 类。

java 复制代码
// 伪代码 - JVM 类加载
ClassLoader cl = ClassLoader.getSystemClassLoader();
Class<?> mainClass = cl.loadClass("MainClassName");

链接(Linking)

加载后,类会经过以下链接步骤:

  1. 验证(Verification):确保加载的类符合 JVM 规范,检查格式、语法、安全性等。
  2. 准备(Preparation):为类的静态字段分配内存,并设置默认初始化值。
  3. 解析(Resolution):将常量池中的符号引用替换成直接引用。

在 HotSpot 的源码中,可以在 instanceKlass.cpp 中找到类链接的实现。

初始化(Initialization)

类初始化包括为静态变量赋值及执行静态代码块。

java 复制代码
// Java 代码 - 类初始化
public class Example {
    static {
        // 代码块,类初始化时执行
        System.out.println("Class Example is initialized.");
    }
}

在 HotSpot 实现中,查看 InstanceKlass::initialize() 方法可以看到类初始化的过程。

执行(Execution)

类被初始化后,JVM 会调用 main 方法开始执行程序。

java 复制代码
// 伪代码 - JVM 执行 main 方法
Method m = mainClass.getMethod("main", String[].class);
m.invoke(null, (Object)args);

在 HotSpot VM 源码中,解释器执行字节码的部分由 interpreter.cpp 实现,而 JIT 编译则由 c1_Compiler.cppc2_Compiler.cpp 等文件实现。

垃圾回收(Garbage Collection)

JVM 在堆内存管理对象实例。当对象不再引用时,垃圾收集器会回收内存。这个过程是自动的,但是可以通过代码触发。

java 复制代码
System.gc(); // 提示 JVM 进行垃圾回收

垃圾回收的代码分布在 HotSpot 源码中的 share/vm/gc/ 目录下。

退出(Shutdown)

程序执行完毕后或者调用 System.exit() 会触发 JVM 退出流程,JVM 会卸载载入的类,并释放所有的资源。

HotSpot VM 中处理类卸载的相关代码通常在 classLoader.cppsystemDictionary.cpp 中。

总结:

以上各阶段的细节均可在 OpenJDK 的 HotSpot 源码中找到。要理解这些源码,需要具备 C++ 语言的知识,同时对 JVM 的内部结构和工作原理有较深理解。每个 JVM 实现的具体细节可能有所不同,但它们都遵循 JVM 规范。

为了更深入地理解 JVM 的工作原理,建议查阅《深入理解 Java 虚拟机》等专业书籍,并在具备一定基础后,直接阅读 OpenJDK 的源码。同时,可以通过调试工具(如 VisualVM 或 JConsole)来实时监控 JVM 的性能指标和行为。这样做可以帮助你更好地理解 JVM 的运行机制。

相关推荐
玉红7771 小时前
R语言的数据类型
开发语言·后端·golang
lvbu_2024war012 小时前
MATLAB语言的网络编程
开发语言·后端·golang
问道飞鱼2 小时前
【Springboot知识】Springboot进阶-实现CAS完整流程
java·spring boot·后端·cas
Q_19284999063 小时前
基于Spring Boot的电影网站系统
java·spring boot·后端
豌豆花下猫3 小时前
Python 潮流周刊#83:uv 的使用技巧(摘要)
后端·python·ai
凡人的AI工具箱3 小时前
每天40分玩转Django:Django部署概述
开发语言·数据库·后端·python·django
SomeB1oody3 小时前
【Rust自学】7.2. 路径(Path)Pt.1:相对路径、绝对路径与pub关键字
开发语言·后端·rust
SomeB1oody3 小时前
【Rust自学】7.3. 路径(Path)Pt.2:访问父级模块、pub关键字在结构体和枚举类型上的使用
开发语言·后端·rust
Bony-4 小时前
Go语言反射从入门到进阶
开发语言·后端·golang
凡人的AI工具箱5 小时前
每天40分玩转Django:Django Email
数据库·人工智能·后端·python·django·sqlite