jvm-类加载过程
加载
- 通过类的全名获取其二进制字节流
- 将字节流代表的静态结构转化为方法区识别的运行时数据结构
- 在内存中实例化这个类的java.lang.Class对象(不一定是堆内存中的,HotSpot就将Class对象放在了方法区里),程序访问这个类在方法区中的类型数据时会通过这个类去访问
连接
验证
- 文件格式验证:校验字节流是否符合Class文件的格式
- 元数据验证:校验语义是否符合java语言规范的要求
- 字节码验证:校验类的方法体,确定语义是否符合逻辑
准备
为类变量分配内存并设置类变量的初始值,这里的初始值并不是代码赋的值,二十数据类型的默认值,如public static final int value = 123
;在准备阶段会被赋值为0,而不是123。
但是如果变量使用final修饰,则会在准备节点赋值为123
解析
此阶段会将常量池的符号引用转为直接引用
- 符号引用:以一组符合来描述引用的目的
- 直接引用:就是我们常说的指针或者句柄,直接引用的目标一定会在虚拟机内存中存在
初始化
到了初始化阶段,jvm才真正开始执行类中定义的java代码
- 初始化节点是执行类构造器<clinit>()方法的过程。类构造器<clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块中的语句合并产生的
- 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先出发其父类的初始化
- 虚拟机会保证一个类的<clinit>()方法在多线程环境中被正确加锁和同步