Java类加载机制与JVM启动过程详解

Java类加载机制与JVM启动过程详解 Java类加载机制与JVM启动过程详解本文档整理了关于Java类加载过程、类加载器触发机制、类加载范围以及JVM启动方式的讨论内容以问答形式呈现并辅以清晰的要点和图示。1. 如何记忆Java类加载的过程Java类加载主要分为五个阶段加载、验证、准备、解析、初始化。为了便于记忆可以采用以下方法记忆口诀加载 → 链接 → 初始化三大步链接又分为验证 → 准备 → 解析英文首字母L V P R I→ 联想句子Let’s Very Patiently Run It让我们非常耐心地运行它形象记忆做一道菜阶段对应动作解释加载去超市买菜将类的二进制字节流读入内存生成Class对象验证检查食材是否安全确保字节流符合JVM规范不会危害虚拟机安全准备洗菜、切菜为静态变量分配内存并设置默认初始值如0、null解析对照菜谱搭配将符号引用替换为直接引用类、方法、字段的具体内存地址初始化开火烹饪执行静态代码块给静态变量赋正确的初始值每个阶段的关键词速记加载找class文件 → 读入内存 → 生成Class对象验证检查格式、语义、字节码安全性准备静态变量分配内存 默认值注意此时不是代码中赋的值解析符号引用 → 直接引用初始化执行静态语句块、静态变量赋值按代码顺序2. 类加载器是如何被触发的触发顺序是怎样的入口是main方法吗2.1 类加载器如何被触发类加载器本身是Java对象除引导类加载器外由JVM在启动阶段创建。类加载请求的产生时机包括遇到new、getstatic、putstatic、invokestatic字节码指令如new对象、访问静态字段、调用静态方法反射调用如Class.forName()初始化子类时触发父类加载但父类可能已加载JVM启动时加载包含main()的主类动态代理、Lambda表达式、JSP等动态生成类的场景总结类加载器并非主动触发而是程序运行需要某个类时JVM通过类加载器加载该类。2.2 类加载器的触发顺序双亲委派模型JVM启动时按以下顺序创建类加载器引导类加载器C实现加载核心类库JAVA_HOME/lib扩展类加载器由引导类加载器加载ExtClassLoader负责加载JAVA_HOME/lib/ext应用程序类加载器由扩展类加载器加载AppClassLoader负责加载classpath下的类当一个类加载请求出现时请求的委派顺序是从子到父向上传递而实际加载尝试的顺序是从父到子向下查找应用程序类加载器收到请求 → 委派给扩展类加载器 → 委派给引导类加载器引导类加载器尝试加载若找到则返回→ 否则扩展类加载器尝试加载 → 否则应用程序类加载器尝试加载2.3 main方法是入口吗main方法所在的类是JVM启动后第一个被显式加载的用户类但类加载器的触发在main之前就已开始加载主类本身。main方法执行过程中遇到其他类的使用如new、反射等会继续触发类加载。因此main方法是程序执行的入口但不是类加载的唯一触发入口。3. 引导类加载器和扩展类加载器会在JVM启动时加载所有类吗不会。两者均遵循**按需加载懒加载**原则只加载程序运行所必需的最核心类以节省内存和加快启动速度。3.1 具体加载范围类加载器加载路径启动时是否加载所有类启动时加载了哪些引导类加载器jre/lib如rt.jar否仅加载JVM和程序启动必需的核心类如java.lang.Object扩展类加载器jre/lib/ext否几乎不加载直到程序中第一次使用到ext中的某个类3.2 为什么不是全部加载节省内存JDK包含成千上万个类全部加载会消耗大量内存。加快启动速度加载类需要磁盘I/O和字节码解析懒加载能显著提升启动时间。按需使用大多数程序只用到一小部分核心类。3.3 验证方法添加JVM启动参数-XX:TraceClassLoading运行一个简单的HelloWorld程序观察加载日志你会发现只有少量核心类被加载而非整个rt.jar。4. JVM启动是如何触发的是通过运行java -jar命令吗是的运行java命令包括java -jar是触发JVM启动最常见的方式。4.1java -jar命令的执行流程操作系统shell调用java可执行文件启动器。启动器创建一个新的操作系统进程并加载JVM动态链接库如jvm.dll或libjvm.so。初始化JVM内部环境创建引导类加载器、内存空间、垃圾回收器等。解析命令行参数若使用-jar从JAR包的META-INF/MANIFEST.MF中读取Main-Class属性作为主类。若直接指定类名如java com.example.Main则将该类作为主类。通过应用程序类加载器加载主类并执行其main方法。4.2 其他触发JVM启动的方式通过JNI调用在本地代码C/C中调用JNI_CreateJavaVM函数在现有进程中嵌入JVM如浏览器运行Applet。通过特定工具或容器如javawWindows无控制台、Docker容器启动Java应用等。4.3 与类加载过程的关系JVM启动 → 创建引导类加载器 → 加载核心类 → 创建扩展和应用程序类加载器 → 加载主类 → 按需加载其他类遵循双亲委派模型。java -jar是整个链条的起点。总结类加载过程加载、验证、准备、解析、初始化可用口诀或形象记忆。类加载器触发按需触发遵循双亲委派模型请求向上委派加载尝试向下进行。类加载范围引导和扩展类加载器均懒加载不会预加载所有类。JVM启动通过java命令创建JVM进程初始化环境后加载主类并执行main方法。