阅读《深入理解Java虚拟机》补充JVM知识体系系列(三)之类加载过程

2021/04/09 JVM 共 1050 字,约 4 分钟

本篇将介绍类加载过程中的一些小细节

类加载过程

Loading

  • 我们以前在提到Loading的时候就简单地说Loading过程就是将class文件加载到内存,其实这里面还是存在一些细节的
    1. 通过类的全限定名将class的二进制文件加载到内存
    2. 将class文件中的静态数据结果转换为运行时数据区的结构
    3. 生成一个class对象存入内存

Verification

  • 我们以前提到Verification只是简单地提了一下,说这个过程会对类进行检验,但是其实Verification过程是整个类加载过程中消耗时间最长的,我们来稍微详细地介绍一下

    1. 文件格式验证

      • 验证魔数是否是CAFEBABE

      • 验证class文件的版本(如果当前JVM的版本低于class文件的版本,那么直接拒绝)

      • 常量池进行检测

        ………

      • 可以说,文件格式验证有非常多的部分,这里仅仅只是列出了九牛一毛,感受一下文件格式验证过程到底在干什么事

    2. 元数据验证

      • 这个类是否有父类(除了Object,所有类都应该有父类)

      • 这个类是否继承了不允许继承的类(被final修饰的类)

      • 这个类是否实现了这个类实现的接口的所有方法(或者父类中的抽象方法)

        ………

      • 元数据验证过程就是为了检测class文件中是否存在违背《Java语言规范》中的规定,也就是大家俗称的语法检验

    3. 字节码检验

      这个过程是整个Verification过程中最最复杂的验证环节,保证被验证的class文件会不会做出对JVM产生危害的举动,例如

      1. 把一个子类对象赋值给父类,这是允许的,但是不允许把一个父类对象赋值给一个子类对象

      2. 防止在操作数栈中放入一个 int 但是却在本地变量表中存入的是long类型

        ………

      字节码验证并不是万能的,只能说没有通过字节码验证一定是有错误的;通过了字节码验证也不能保证一定正确

    4. 符号引用验证

      1. 这个符号引用的全限定名是否可以找到对应的类

      2. 符号引用指向的类的权限修饰符(access_flag)是否能够被允许访问(例如不在同一个包内,那么private是不允许访问的)

        ………

Preparation

  • 这个阶段就是将类中的静态变量赋予默认值,被final修饰的赋予初始值

Resolution

  • 这个阶段要做的事情就是将常量池中的符号引用变成直接引用

Initialization

  • 这个阶段是类加载的最后一个步骤,做的事情其实就是将一开始赋予了默认值的静态变量赋予初始值
  • 这个过程其实是调用了方法,这个方法其实没有什么,只要一个类拥有static{}语句块,或者初始化的赋值操作,那么方法就会被创建,通过这个方法来对static静态变量赋予默认值

文档信息

Search

    Table of Contents