类加载有三个阶段:
加载、连接、初始化
一、加载
-
由c++ (InstantKlass c++的一种数据结构 用来 描述类的信息)加载类信息到元空间(java 1.8)同时在堆中生成类的镜像 。元空间 和堆 内生成类的镜像 地址互相引用。方便 在 创建类对象时 根据地址找到 元空间访问 对应的 field 和method
[图片上传中...(6b7e986c2b7f2179fcb6d432f3462e1.png-40f017-1578298317874-0)]
二、连接
1. 验证
- 验证class 文件是否 满足 JVM 规范。 例如 修改 class 文件 里的 cafebe ,执行时会报 java formart error。
2. 准备
- 为static 变量分配空间 ,设置默认值
- static 变量在JDK 7之前 存储于instanceKlass 末尾,从JDK 7开始 ,存储于 _java_mirror末尾。
- static 变量分配空间和赋值是两个步骤,分配空间在准备阶段完成,赋值在初始化阶段完成
- 如果static变量是final的进本类型,那么编译阶段值就确定了,赋值在准备阶段完成
- 如果static变量是final ,但属于引用类型,那么赋值也会在初始化阶段完成
3.解析
将常量池中的符号引用解析为直接引用 (知道具体的类的内存地址)