主页 > 创业  > 

JVM基础---java类加载机制(类的生命周期,类加载器,双亲委派模型)

JVM基础---java类加载机制(类的生命周期,类加载器,双亲委派模型)

文章目录 类的生命周期类的加载:查找并加载类的二进制数据验证准备解析初始化 类加载器启动类加载器(Bootstrap ClassLoader)扩展类加载器(Extension ClassLoader)应用程序类加载器(Application ClassLoader)自定义类加载器(User-Defined ClassLoader) 双亲委派模型工作原理优点打破双亲委派打破双亲委派


类的生命周期

类加载的过程包括了加载、验证、准备、解析、初始化五个阶段。在这五个阶段中,

加载、验证、准备和初始化这四个阶段发生的顺序是确定的,而解析阶段则不一定,它在某些情况下可以在初始化阶段之后开始,这是为了支持Java语言的运行时绑定(也成为动态绑定或晚期绑定)。另外注意这里的几个阶段是按顺序开始,而不是按顺序进行或完成,因为这些阶段通常都是互相交叉地混合进行的,通常在一个阶段执行的过程中调用或激活另一个阶段。

类的加载:查找并加载类的二进制数据 任务:将类的字节码文件(.class 文件)加载到内存中。

具体步骤:

通过类的全限定名(包名 + 类名)查找字节码文件。将字节码文件读取到内存中。在内存中生成一个代表该类的 java.lang.Class 对象。

加载.class文件的方式

从本地系统中直接加载通过网络下载.class文件从zip,jar等归档文件中加载.class文件从专有数据库中提取.class文件将Java源文件动态编译为.class文件 验证 任务:确保加载的字节码是合法的,符合 JVM 规范。验证内容: 文件格式验证: 检查字节码文件是否符合 JVM 规范(如魔数、版本号等)。 元数据验证: 检查类的元数据是否合法(如是否有父类、是否继承了 final 类等)。 字节码验证: 检查方法体中的字节码指令是否合法,是否会危害 JVM。 符号引用验证: 检查类、方法、字段的引用是否存在且可访问。 准备

任务:为类的静态变量分配内存,并设置默认初始值。

具体行为:

静态变量会被分配内存并初始化为零值(如 int 初始化为 0,boolean 初始化为 false)。如果是常量(static final),则直接赋值为指定的值。

示例:

static int a = 10; // 准备阶段:a = 0 static final int b = 20; // 准备阶段:b = 20 解析 任务:将常量池中的符号引用转换为直接引用。符号引用:一组符号描述引用目标(如类名、方法名)。直接引用:指向目标在内存中的指针或偏移量。解析内容: 类或接口的解析。字段的解析。方法的解析。 初始化 任务:执行类的静态初始化代码(静态代码块和静态变量赋值)。触发条件: 创建类的实例(new)。访问类的静态变量或静态方法。使用反射加载类(如 Class.forName())。初始化子类时,父类会先被初始化。 static int a = 10; // 初始化阶段:a = 10 static { System.out.println("Static block executed"); } 类加载器

JVM 通过类加载器来加载类。Java 中有以下三类类加载器:

启动类加载器(Bootstrap ClassLoader) 职责:加载 JVM 核心类库(如 java.lang.*、java.util.* 等)。实现:由 JVM 自身实现,通常是用 C/C++ 编写的。路径:加载 JAVA_HOME/lib 目录下的类。 扩展类加载器(Extension ClassLoader) 职责:加载扩展类库(如 javax.* 等)。实现:由 sun.misc.Launcher$ExtClassLoader 实现。路径:加载 JAVA_HOME/lib/ext 目录下的类。 应用程序类加载器(Application ClassLoader) 职责:加载用户类路径(ClassPath)下的类。实现:由 sun.misc.Launcher$AppClassLoader 实现。路径:加载 -classpath 或 -cp 指定的类。 自定义类加载器(User-Defined ClassLoader) 职责:用户可以通过继承 ClassLoader 类实现自定义类加载器。用途: 热部署:在不重启 JVM 的情况下重新加载类。模块化加载:加载特定模块的类。加密类加载:加载加密的字节码文件。 双亲委派模型

双亲委派模型是类加载器之间的协作机制。

工作原理 当一个类加载器需要加载类时,它首先会委托给父类加载器加载。如果父类加载器无法加载,子类加载器才会尝试加载。最终,如果所有父类加载器都无法加载,才会抛出 ClassNotFoundException。 优点 安全性:防止用户自定义的类替换核心类(如 java.lang.String)。避免重复加载:确保类只被加载一次。 打破双亲委派 在某些场景下(如 SPI 服务加载、模块化加载),可能需要打破双亲委派模型。安全性:防止用户自定义的类替换核心类(如 java.lang.String)。避免重复加载:确保类只被加载一次。 打破双亲委派 在某些场景下(如 SPI 服务加载、模块化加载),可能需要打破双亲委派模型。例如:Thread.currentThread().setContextClassLoader() 可以设置线程上下文类加载器。
标签:

JVM基础---java类加载机制(类的生命周期,类加载器,双亲委派模型)由讯客互联创业栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“JVM基础---java类加载机制(类的生命周期,类加载器,双亲委派模型)