虚拟机类加载机制
一、类加载的时机
一个类型从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期将会经历加载(Loading)、验证、准备、解析、初始化、使用和卸载7个阶段,其中验证、准备、解析三个部分称为连接。
类的生命周期
有且只有六种情况必须立即对类进行**“初始化”**(而加载、验证、准备自然要在此之前进行):
1.遇到new、getstatic、putstatic或invokestatic这四条字节码指令时。能够生成这四条指令的典型Java场景有:
- 使用new关键字实例化对象的时候
- 读取或者设置一个类型的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外)的时候
- 调用一个类型的静态方法的时候
2.使用java.lang.reflect包对类型进行反射调用,如果没有金洗过初始化,则需要先触发
3.当初始化类,发现其父类没有进行过初始化
4.当虚拟机启动时,用户需要制定一个要执行的主类
5.没看懂
6.当一个接口中定义了JDK8新加入的默认方法,如果有这个接口的实现类发生了初始化,那该接口要在其之前被初始化1··
二、类加载的过程
1.加载
在加载阶段,Java虚拟机需要完成以下三件事情:
- 通过一个类的全限定名来获取定义此类的二进制字节流
- 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
- 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口
加载阶段结束后,Java虚拟机外部的二进制字节流就按照虚拟机所设定的格式存储在方法区中了,类型数据妥善安置在方法区后,会在Java堆内存中实例化一个java.lang.Class的对象
2.验证
这一阶段的目的是确保Class文件的字节流中包含的信息符合《Java虚拟机规范》的全部约束要求,保证这些信息被当做代码运行后不会危害虚拟机自身的安全
验证阶段会完成下面四个阶段的校验动作:
1.文件格式验证
验证字节流是否符合Class文件格式的规范
2.元数据验证
3.字节码验证
4.符号引用验证
3.准备
准备阶段是正式为类中定义的变量,即被static修饰的变量分配内存并设置为“零值”的阶段
4.解析
解析阶段是Java虚拟机将常量池内的符合引用替换为直接引用的过程
5.初始化
直到初始化阶段,Java虚拟机才真正开始执行类中编写的java程序代码,将主导权移交给应用程序。进行准备阶段时,变量已经赋过一次系统要求的初始零值,而在初始化阶段,则会根据程序员通过编码制定的主观计划去初始化类变量和其他资源
static代码块也是在这个阶段进行