Java虚拟机结构、内存管理相关基础知识(2)

类加载机制

类的整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段
类加载的过程包括了:加载->验证->准备 ->解析-> 初始化
按顺序开始,而不是按顺序进行或完成,通常都是互相交叉地混合进行,在一个阶段执行的过程中调用或激活另一个阶段

  • 加载
    通过一个类的全限定名来获取定义的二进制字节流,将这个字节流保存到方法区,在java堆中生成一个代表这个类的java.lang.Class对象,和堆中数据关联起来
    加载阶段可控性最强,因为类的加载器可以用系统的,也可以用自己写的加载器(ClassLoader

  • 验证
    确保Class文件中的字节流包含的信息符合当前虚拟机的要求,不会危害虚拟机的自身安全(Class文件不一定是java代码编译过来的)
    验证包括四个阶段:
    文件格式的验证(验证字节流是否符合Class文件格式的规范,并且能否被当前版本的虚拟机版本处理),
    元数据的验证(对类的元数据信息进行语义校验,保证所有元数据信息都符合java语法规范),
    字节码验证(进行数据流和控制流分析,对类的方法进行校验分析,以保证被校验的类的方法在运行时不会做出危害虚拟机安全的行为),
    符号引用验证(这是最后一个阶段,主要对类自身以外的信息进行匹配性校验)

  • 准备
    为类变量(静态变量)分配内存,并设置类变量初始值的阶段

内存分配仅包括类变量(static),不包含实例变量,实例变量会在对象实例话时随着对象一起分配在java堆中
前面设置的初始值通常情况下是数据类型默认的零值(如:0,0L,null,false,ect),而不是被在java代码中被显示地赋予的值
public static int value =100;这时value=0
public static final int value=100;这时value=100(特例)
  • 解析
    虚拟机将常量池中的符号引用转化为直接引用的过程,虚拟机实现对第一次解析的结果进行缓存(在运行时常量池中记录直接引用,并把常量标示为解析状态),从而避免解析动作重复进行。
    解析动作主要针对类或接口、字段、类方法、接口方法四类符号引用进行
  • 初始化
    类初始化是类加载的最后一个阶段,到初始化阶段,才是真正开始执行类中的java程序代码
    • 什么时候进行初始化?
     1、 当遇到new、getstatic、putstatic、invokestatic这四条字节码指令时,如果类还没有进行过初始化则开始进行初始化
     2、使用java.lang.refect包的方法对类进行反射调用时,如果类还没有进行过初始化
     3、 当初始化一个类的时候,如果发现其父类还没有进行初始化,则需要先触发父类的初始化
     4、 当虚拟机启东时,用户需要指定一个要执行的主类,虚拟机先执行该主类。

只要这四种情况才会触发类的初始化,称为对一个类进行主动引用,除此之外的所有引用类的方式都不会触发初始化,诚为被动引用

你可能感兴趣的:(Java虚拟机结构、内存管理相关基础知识(2))