https://www.bilibili.com/video/BV1he4y1e7nW
将类的字节码载入方法区中,内部采用 C++ 的 instanceKlass 描述 java 类,它的重要 field 有:
_java_mirror 即 java 的类镜像,例如对 String 来说,它的镜像类就是 String.class,作用是把 klass 暴露给 java 使用
_super 即父类
_fields 即成员变量
_methods 即方法
_constants 即常量池
_class_loader 即类加载器
_vtable 虚方法表
_itable 接口方法
如果这个类还有父类没有加载,先加载父类 加载和链接可能是交替运行的 instanceKlass 这样的【元数据】是存储在方法区,但 _java_mirror 是存储在堆中 instanceKlass和_java_mirror(java镜像类)互相保存了对方的地址 类的对象在对象头中保存了 *.class 的地址。让对象可以通过其找到方法区中的instanceKlass,从而获取类的各种信息
验证类是否符合 JVM规范,安全性检查
为 static 变量分配空间,设置默认值
static变量在JDK 7以前是存储与instanceKlass末尾。但在JDK 7以后就存储在_java_mirror末尾了 static变量在分配空间和赋值是在两个阶段完成的。分配空间在准备阶段完成,赋值在初始化阶段完成 如果 static 变量是 final 的基本类型,以及字符串常量,那么编译阶段值就确定了,赋值在准备阶段完成 如果 static 变量是 final 的,但属于引用类型,那么赋值也会在初始化阶段完成
将常量池中的符号引用解析为直接引用
将类的名字解析为方法区中的地址
初始化即调用 <cinit>()
,虚拟机会保证这个类的【构造方法】的线程安全