jvm类加载流程学习记录

40 阅读2分钟

image.png 类的加载流程主要分为加载,连接,卸载,使用,初始化,其中连接还可以分为验证,准备,解析。 但实际上这些流程都是按顺序穿插进行的,例如加载过程中,实际上也会进行字节码的验证等等。 所以实际流程应该为

  1. 通过类的全限定名获取到类的字节流
  2. 加载的时候验证文件的格式,确保class文件中的信息集合符合java虚拟机规范 主要验证class文件结构是否正确,例如是否以魔数开头,主次版本号是否被虚拟机识别,如java9不支持jdk8之前的java版本,常量池的索引值是否指向不存在的常量或不符合类型的常量等
  3. 将静态结构转换为运行时结构,也就是加载到方法区中,方法区主要存储各种类型信息
  4. 元数据验证,主要对对象进行语义检查,基本上ide已经进行了该校验
  5. 字节码验证,这个也是验证过程中最复杂的验证,主要是对方法表中的数据进行校验,例如类型转换操作栈中放置了int属性,使用时却按long类型使用等,jdk6后将这过提前到编译期进行,并形成StackMapTable属性,这是字节码验证时,只需要遍历StackMapTable中是否有问题即可
  6. 符号应用验证,校验符号引用中的地址能否找到类,引用的类,字段是否可以被当前类访问(private、protected、public)等
  7. 全部验证通过后,才会真的形成一个class对象,并放置在堆内存中,且各种类型的数据的访问地址会直接指向方法区来查询对应的属性
  8. 形成对象后,会对类的一些静态变量进行内存分配,也就是赋值初值,这里进行分配的只是类变量例如public static int value = 123,且此时赋值的时初始值也就是零值,因为这是还没有调用类的方法也就是构造方法,所以还未进行变量真正的赋值操作 最后再将类的常量池中所有的符号引用转化为直接引用,也就是对字段,类,接口等信息进行解析,直接指向对应的目标的句柄,虚拟机在解析常量引用的时候,会将以解析完的常量进行标识,从而避免解析动作的重复执行

至此类的整体加载流程就完毕了