JVM 虚拟机的类加载过程

主要阶段还是: 加载–>验证–>准备–>解析–>初始化–>使用–>卸载(这几个阶段)每个阶段不是顺序完成的,而是交叉进行,例如:加载还没结束,有可能连接阶段(验证、准备、解析)已经开始。每个阶段做了什么事情?

  1. 加载:
    1. 通过类的全限定名获取定义此类的二进制字节流。
    2. 通过将这个字节流代表的静态结构转化为方法区的运行时数据结构。
    3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

加载阶段获取字节流,但是没说具体从哪加载,如何加载,这样在这个阶段是开发人员可控性最强的阶段。可以从哪里加载字节流?
1. zip 包加载
2. 网络中获取
3. 运行时计算生成,
4. proxy
5. 其它文件生成
6. 数据库读取

类是通过类加载器加载,数据则是由JVM 直接创建,但数据中的元素跟类加载器有关。
2. 验证: 作用: 为了确保Classe文件的字节流中包含的信息符合当前虚拟机要求,并且不会危害虚拟机自身的安全。验证阶段非常重要,在类加载系统中占了相当大一部分,主要分为以下4个阶段。
1. 文件格式验证

	1. 验证自己留是否符合Class文件规范,能被当前虚拟机处理

		1. 是否以魔术 0xCAFEBABF开头
		2. 主次版本号是否在当前虚拟机处理范围内
		3. 常量池中的常量是否有不被支持的常量类型
		4. ......
2. 元数据验证

	1. 对字节码进行语义分析,保证描述信息符合java语言规范。

		1. 判断类是否存在父类
		2. 是否继承了不该继承的类
		3. 类不是抽象类,是否实现了父类接口或要求实现的方法
		4. ....
3. 字节码验证

	1. 最复杂的一个阶段,对数据流和控制流分析,判断程序、逻辑是否合法。

		1. 保证操作数栈的数据类型和指令代码能配合工作
		2. 保证指令不会跳转到方法以外的字节码指令上。
		3. 保证方法中的类型转换是有效的。
	2. 使用 StackMapTable 优化字节码验证。
4. 符号引用验证

	1. 作用是将符号引用转换为直接引用的过程。主要是针对常量池的各种符号引用的信息进行匹配校验。

		1. 通过字符串全限定名能否找到对应的类
		2. 类中是否存在复合方法的字段描述符以及简单名称 所描述的方法和字段。
  1. 准备: 准备阶段主要是为类变量(static修饰)分配内存并设置类变量初始值。类变量所使用的内存在方法区进行分配。 注意: 类变量是static修饰的,而非实例变量,实例变量的分配将在对象实例化随着对下那个一起分配在java堆中。 举例: private static int value = 123;value 在准备阶段被赋予默认值0,而123是在初始化阶段才会赋值的。但是常量例外,在准备阶段就赋值了,例如下边代码:private static final int value = 123;

  2. 解析: 将常量池符号引用转为直接引用的过程。

    • 符号引用:任何形式的字面量,引用目标不一定在内存。
    • 直接引用:可以直接指向目标的指针、相对偏移量或一个能间接定位到目标的句柄。直接引用必定在内存中存在。

    解析的动作主要有7种:

    1. 类或接口解析

      1. 类解析使用类加载器解析,如果有父类,去加载父类。
      2. 如果是数据,数组元素为对象,则按照1中解析。如果元素为基本类型,则按照数组维度和元素解析。
      3. 判断类是否具备访问权限。
    2. 字段解析

      1. 查找这个字段所属的类或接口的符号引用

        1. 当前类C 中包含了字段名称和字段描述,直接返回这个字段的直接引用,查找结束。
        2. 如果当前类实现了接口,则按照继承关系,从下往上找接口中是否存在字段名称和字段描述,有则从接口返回。
        3. 如果类C 不是 Object 类,则找父类是否存在这个字段名称和字段描述,有则从从父类中返回。
        4. 还找不到,抛出 异常。
    3. 类方法解析

    4. 接口方法解析

    5. 方法类型解析

    6. 方法句柄解析

    7. 调用点限定符解析

  3. 初始化: 类加载阶段除了加载阶段可以自定义类加载器以为,其余动作都由虚拟机主导和控制。这个阶段才开始执行类中定义的java程序代码(或者说是字节码) 准备阶段变量被设置初始值,在初始化阶段则根据程序员主观指定的程序计划去初始化类变量和其他资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值