类的加载过程(深入理解jvm)

编程

1.1.通过类的全限定名找到二进制字节流

1.2.将字节流中的静态存储结构转化为方法区中的动态存储结构

1.3.在内存中生成一个java.lang.Class对象作为方法区这个类各种数据的访问入口

2.验证:校验字节码文件是否符合规则,是否会破会虚拟机的安全性

2.1.文件格式验证(是否符合class格式要求,可以被虚拟机解析)

2.2.元数据验证(按要求实现接口继承父类etc..)

2.3.字节码验证(数据类型转换是否允许etc...)

3.准备:给类变量在方法区分配内存并赋“零值”(区别于实例化时给实例变量和实例对象在堆区分配内存)

3.1.如果是final修饰的类变量在此阶段会直接根据设置的常量赋值

4.解析:将符号引用(与内存布局无关)转换为直接引用(于内存布局有关,如果存在直接引用,则一定存在于内存中)的过程,解析的结果会在常量池中缓存避免重复解析(除了invokedynamic指令)

4.1.类和接口解析

4.2.字段解析

4.3.类方法解析

4.4.接口方法解析(接口方法一般是public修饰,不存在访问性检查)

5.初始化:<clinit>()类构造器

5.1.<clinit>()是虚拟机自动收集类变量和静态语句块代码合并生成。在静态块后面声明的类变量,在静态块中只可赋值不可访问

5.2.父类的<clinit>()一定先执行,父接口的<clinit>()方法不用先执行,用到父接口时才会执行

5.3.<clinit>()方法不是必须的,如果类或接口没有静态语句块和变量的赋值就不会生成这个方法

5.4.虚拟机会保证多线程情况下只有一个线程执行<clinit>()方法,其他线程在它执行完之前都会阻塞

以上是 类的加载过程(深入理解jvm) 的全部内容, 来源链接: utcz.com/z/515362.html

回到顶部