声明:本文内容引用来自《深入理解Java虚拟机JVM高级特性与最佳实践》(第二版)
1.概述
虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成呢个可以呗虚拟机直接使用的Java类型,这就是虚拟机的类加载机制
2.生命周期
加载、验证、准备、解析、初始化、使用和卸载
3.何时加载?
有且只有:
a.遇到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果没有初始化,则触发起初始化(new 实例化对象,读取或设置一个静态(final修饰)字段,以及调用一个类的静态方法)
b.使用 java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行初始化,则初始化
c.当初始化一个类的时候,如果发现其父类还没进行初始化,则初始化
d.当虚拟机启动时,用户指定一个要指定一个要执行的主类,虚拟机会先初始化这个主类
e.当使用1.7的动态语言支持时,如果一个java.lang.invoke.MethomdHandle实例最后的解析结果REF_getStatic、REF_putStatic、Ref_invokeStatic的方法句柄,并且这个方法句柄所对应的类
没有进行过初始化
4.类加载过程
a).加载
i).通过一个类的全限定名来获取定义此类的二进制字节流
ii).将这个字节流所代表的静态存储结构转化为方法去的运行时数据结构。
iii).在内存中生成一个代表这个类的Classduixiang,作为方法区这个类的各种数据的访问入口
备注:数组的加载过程
i).如果数组的组件类型是引用类型,那就递归加载这个组件类i系那个,数组C将在家在该组件类型的类加载器的类名称空间上被标识
ii).如果数组的组件不是引用类型(int[]),jvm将会把数组C标记为与引导类加载器关联
iii).数组类的可见性与它的组建类型的可见性一致,如果组件类型不引用类型,那数组类的可见性将默认为public
b).验证
i).文件格式验证
是否以模数0xCAFEBABE开头
常量池的常量中是否有不被支持的常量类型
ii).元数据验证
类是否有父类
类的父类是否继承了不允许被继承的类(final修饰)
若这个类不是抽象类,是否实现父类或接口要求实现的所有函数
类中字段、方法是否与父类产生矛盾
iii).字节码验证
iiii).符号引用验证
c).准备
是正式为类变量分配内存并设置类变量初始值的阶段,这些类变量都将在方法去中进行分配。容易混淆的地方:首先这个时候进行内存分配的仅包括类变量,不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在java堆中
d).解析
是jvm将常量池内的符号引用替换为直接引用的过程
i).类或接口的解析
ii).字段解析
iii).类方法解析
iiii).接口方法解析
e).初始化
最后一步。初始化是执行类构造器<clinit>()方法的过程。
下篇文章将分享虚拟机中类的加载器,敬请关注。
本文暂时没有评论,来添加一个吧(●'◡'●)