二、类加载机制

类加载过程

类被加载入 JVM 后,整个生命周期分为七个阶段:加载、验证、准备、解析、初始化、使用和卸载(验证、准备、解析这三个阶段统称为连接)

除去使用和卸载,剩余 5 个阶段顺序发生,就是 Java 的类加载过程(但在动态绑定的情况下,解析阶段发生在初始化阶段之后)

Loading 加载

将字节码转化为二进制字节流加载到内存中,并生成一个代表该类的 java.lang.Class 对象

Verification 验证

该阶段会对二进制字节流进行校验,只有符合 JVM 字节码规范的才能被 JVM 正确执行

Preparation 准备

该阶段对类变量(也称为静态变量,static 关键字修饰的)分配内存并初始化对应数据类型的默认初始值,如 0、0L、null、false 等

public String str1 = "111";
public static String str2 = "222";
public static final String str3 = "333";

str2会被作为类变量分配内存,且初始值为null而不是222,真正的赋值会在 Initialization 初始化阶段

str3会被作为常量变量加载入类的常量池,直接赋值333

Resolution 解析

该阶段将常量池中的符号引用转化为直接引用,将“编译时”和“运行时”解耦

符号引用:

以一组符号(无歧义的定位到目标的字面量)来描述所引用的目标

定义:包含了类、字段、方法、接口等多种符号的全限定名

特点:在编译时生成,存储在编译后的字节码文件的常量池中

直接引用:

通过对符号引用进行解析,找到引用的实际内存地址

定义:直接指向目标的指针、相对偏移量或者能间接定位到目标的句柄

特点:在运行时生成,依赖于具体的内存布局

效率:由于直接指向了内存地址或者偏移量,效率更高

若不涉及动态加载,则进行一次解析后的解析结果可以一直使用

但使用了动态加载,解析结果会根据不同情况发生变化。所以动态加载时,解析阶段在初始化后执行,现解析现使用

Initialization 初始化

在准备阶段,类变量已经被赋过默认初始值,而在初始化阶段,类变量将被赋值为代码期望赋的值

类加载器

概念

类加载器是 JVM 中用于动态加载类文件的组件。它将 .class 文件中的字节码加载到内存中,并将其转换为 Class 对象,以供 JVM 执行

对于任意一个类,都需要由它的类加载器和这个类本身一同确定其在 JVM 中的唯一性

作用

动态加载类:在运行时根据需要加载类,而不是在编译时加载所有类

隔离不同的类命名空间:通过不同的类加载器,可以隔离同名类,使得它们不会相互冲突

双亲委派模型

概念

类加载器在尝试加载一个类时,首先会委派给其父加载器去尝试加载这个类,只有在父加载器无法加载该类时,子加载器才会尝试自己去加载

特点

1)递归委派:这个过程会递归向上进行,从启动类加载器开始,再到扩展类加载器,最后到系统类加载器

2)优先父加载器:如果父加载器可以加载这个类,那么就优先使用父加载器的结果

作用

1)安全性:避免重复加载类。例如 java.lang.Object 类只能由根类加载器加载,防止恶意代码加载不受信任的类来替代系统核心类

2)一致性:保证同一个类在 JVM 中只会被加载一次,确保在整个应用中使用的是同一个类对象

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇