JVM加载类的过程

基本概念
      JVM把class文件加载到内存中变成类共有三大步骤,加载,链接,初始化。其中,链接需要验证类是否符合JVM规范,而没有经过初始化的类,在内存里是不能使用的。

      大家都知道,java语言可以把类型分两大类,基本类型和引用类型。基本类型是由JVM预先定义好的,所以,我们主要讨论的是引用类型。引用类型可以细分为4类:类,接口,数组和泛型。其中,泛型会在编译时被擦除,所以,JVM中的类型只有三种。这三种里,数组是由JVM生成的,而类和接口就有对应的字节流。字节流最常见的就是class文件,初次之外,还有通过网络获取,通过代码生成的方式。不管是什么方式的字节流,JVM都会对其进行统一处理。接下来,就具体介绍一下各个步骤。

加载
      加载是指查找字节流,根据字节创建类的过程。而JVM用来加载字节流的东西,就叫做类加载器。类加载器有由C++实现的启动类加载器。除此之外,其他的类加载器都是java.lang.ClassLoader的子类。这些类加载器在加载字节流的时候,都会先把字节流转发给父类加载器,在父类加载器不能加载该字节流的时候,本身才会尝试去加载,这呢就叫做双亲委派模型。在java9之前,启动类加载器负责加载最基础,最重要的包,除启动类加载器外,还有两个重要的加载器,扩展类加载器和应用类加载器。

      扩展类加载器的父类是启动类,负责加载一些通用,相对来讲更次要一点的包,譬如系统变量 java.ext.dirs制定的类。
应用类加载器的父类是扩展类,负责加载由jvm参数-cp/-classpath、系统变量java.class.path制定路径下的类。
      java9对类加载器做了些微的调整,扩展类加载器改名为平台加载器,因为java9引入了模块系统,除了几个关键模块(具体是哪些,我了解的也很少)是由启动类加载器加载,其他的都是由平台加载器负责加载。

      在jvm里,类的唯一性是由类的全名+类加载器的实例确定的。同一串字节流被不同的类加载器加载,得到的也是不同的两个类,这也是为什么要使用双亲委派模型。

链接
     链接是指将创建的类合并到jvm里,并确认可以执行的过程。分三个阶段:验证、准备、解析。

     验证:验证的目的是要确保被加载的类能满足JVM的约束条件。当然,由java编译器编译过来的类必然可以满足JVM的约束条件,但JVM执行的东西并不一定是java编译过来的。只需给出对应的字节流,它都能运行,所以要验证对应的字节流是否符合JVM规范。
      准备:准备的目的是为类的静态字段分配内存(而对静态字段的初始化则会在初始化阶段进行),构造和类相关的数据结构(譬如抽象方法动态绑定的方法表)。class文件被加载之前,并不知道其他类,方法字段之类的所对应的具体地址。当类引用方法,字段时,java编译器会生成一个符号引用,在运行阶段,这个符号引用就能无歧义的定位到具体的方法上。
      解析:解析的目的就是把符号引用解析成实际引用。如果符号引用指向一个未被加载的类或字段,方法,在解析过程就会触发这个类的加载阶段,但并不一定会触发链接和初始化。
初始化
      初始化就是给常量字段赋值,执<clinit>方法的过程。<clinit>就是java编译器会把那些非final修饰的静态字段,final修饰的静态非基本类型和非字符串的字段以及静态代码块放在同一个方法里,这个方法名就叫做<clinit>。JVM会通过加锁的方式类确保<clinit>只会被执行一次。只有放初始化完成后,类才能变成可执行状态。

JVM规范例举了以下情况会触发类的初始化

  •     当JVM启动时,用户指定的主类
  •     使用new创建的目标类
  •     类的静态方法被调用
  •     类的静态字段被访问,且不是常量
  •     类的静态字段被赋值
  •     子类的初始化
  •     通过反射class.forName()调用是
  •     初次调用MethodHandle实例
  •     当接口定义了default时,子类的初始化会触发该接口的初始化
     
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二十同学

谢谢大佬打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值