深入理解JVM类加载机制与双亲委派模型

目录

引言

1. 类加载机制概述

(1)加载

(2)验证

(3)准备

(4)解析

(5)初始化

2. 双亲委派模型

工作流程

优点


引言

Java虚拟机(JVM)是Java程序运行的核心,而类加载机制是JVM的一个重要组成部分。理解类加载机制对于Java开发者来说至关重要,因为它涉及到类的加载、链接、初始化等关键过程。本文将深入探讨JVM的类加载机制,并着重介绍其中的双亲委派模型。


1. 类加载机制概述

java 代码会被编译成 class 文件(包含了一些字节码)java 程序要想运行起来,就需要让 jvm读取到这些 .class 文件,并且把里面的内容,构造成类对象,保存到内存的方法区中.

(1)加载

找到 .class 文件,打开文件,读取文件内容(将类的字节码文件加载到内存中)

(2)验证

.class 是一个二进制文件的格式(某个字节都有特定的含义),所以就需要验证你当前读到的这个格式是否符合要求

(3)准备

给静态变量分配内存空间(最终的目标是构造出类对象),这里是只进行了分配空间,并没有进行初始化。此时空间上的内存的值是全 0。

(4)解析

针对类对象中包含的字符串常量进行处理,进行初始化操作。

java 中代码中的 字符串常量,在编译后也会进入.class文件中。

例如:

final String s = "test";

// 这里的 test 会进入到.class文件中
// 与此同时.class 文件的二进制指令中,也会有一个 s 这样的引用被创建出来~~
// 由于引用里本质上保存的是一个变量的地址,在.class 文件中,这是文件,不涉及到内存地址
// 因此在.class 文件中,s 的初始化语句,就会先被设置成一个"文件的偏移量"
// 通过偏移量,就能找到“test"这个字符串所在的位置
// 当我们这个类真正被加载到内存中的时候,再把这个偏移量,替换回真正的内存地址

(5)初始化

针对类对象进行初始化,把类对象中需要的各个属性都设置好。还初始化 static 成员,执行静态代码块,还可能加载父类。


2. 双亲委派模型

Java的类加载采用了一种层次化的双亲委派模型,它的核心思想是父类加载器在加载类时先委派给子类加载器,只有在子类加载器无法完成加载的情况下,父类加载器才会尝试加载。(是上面“加载”中的一个环节,来找到.class文件)

工作流程

JVM中内置了三个类加载器:

1. Bootstrap ClassLoader(启动类加载器):是最顶层的加载器,负责加载Java的核心库,如java.lang 包。(标准库的目录

2. Extension ClassLoader(扩展类加载器):主要加载 java.ext.dirs 系统变量指定的目录中的类库。(JDK 中的一些扩展库对应的目录

3. Application ClassLoader(应用程序类加载器):也称为系统类加载器,负责加载用户类路径(classpath)上的类库。(搜索项目当前目录和第三方库目录

在类加载时,首先由Bootstrap ClassLoader尝试加载。如果找不到类,再由Extension ClassLoader尝试加载。最后由Application ClassLoader加载。这样的流程保证了在不同层次上的类都能够被加载,并且层次间的类不会相互影响,确保了类的一致性和安全性。

优点

确保了标准库的类,被加载的优先级最高,其次是扩展库,最后是自己写的类和第三方库

你可能感兴趣的:(javaEE,jvm)