一文让你理解Class类加载机制

理解类加载机制

Class文件是各种编译器编译生成的二进制文件,在Class文件中描述了各种与该类相关的信息,但是Class文件本身是一个静态的东西,想要使用某个类的话,需要java虚拟机将该类对应的Class文件加载进虚拟机中之后才能进行运行和使用。

举个例子,Class文件就好比是各个玩具设计商提供的设计方案,这些方案本身是不能直接给小朋友玩的,需要玩具生产商根据方案的相关信息制造出具体的玩具才可以给小朋友玩。那么不同的设计商有他们自己的设计思路,只要最终设计出来的方案符合生产商生产的要求即可。生产商在生产玩具时,首先会根据自己的生产标准对设计商提交来的方案进行阅读,审核,校验等一系列步骤,如果该方案符合生产标准,则会根据方案创建出对应的模具,当经销商需要某个玩具时,生产商则拿出对应的模具生产出具体的玩具,然后把玩具提交给经销商。

对于java而言,虚拟机就是玩具生产商,设计商提交过来的方案就是一个个的Class文件,方案创建的模具就
总的来说,类的加载过程,包括卸载在内的整个生命周期共有以下7个阶段:

加载、验证、准备、初始化、卸载这5个阶段的顺序是确定的,但是解析阶段不一定,在某些情况下解析可以在初始化之后再执行,为了支持java的运行时绑定,也成为动态绑定或晚期绑定。invokedynamic指令就是用于动态语言支持,这里“动态”的含义是必须等到城市实际运行到这条指令的时候,解析动作才开始执行。

加载

“加载”是“类加载”过程中的一个阶段,在加载阶段,虚拟机需要做以下3件事情:

  • 通过类的全限定名获得该类的二进制字节流

  • 将这个字节流所代表的静态存储结构转换成方法区中的某个运行时数据结构

  • 在方法区内存(对于HotSpot虚拟机)中生成一个代表该类的java.lang.Class对象,作为访问方法区中该类的运行时数据结构的外部接口

加载阶段中“通过类的全限定名获得该类的二进制字节流”这个动作,被放到java虚拟机外部实现,目的是最大限度的让应用程序去决定该如何获取所需的类,而实现该动作的代码模块就是类加载器(ClassLoader),JVM提供了3种类加载器:

  • 启动类加载器(Bootstrap ClassLoader):负责加载 JAVAHOME\lib 目录中的,或通过-Xbootclasspath参数指定路径中的,且被虚拟机认可(按文件名识别,如rt.jar)的类。

  • 扩展类加载器(Extension ClassLoader):负责加载 JAVAHOME\lib\ext 目录中的,或通过java.ext.dirs系统变量指定路径中的类库。

  • 应用程序类加载器(Application ClassLoader):负责加载用户路径(classpath)上的类库。

加载阶段完成后,虚拟机外部的二进制字节流就按照虚拟机所需的格式存储在方法区中了。

验证

加载完成后,紧接着(更确切的说是交叉执行)虚拟机会对加载的字节流进行验证。虚拟机如果不检查输入的字节流,对其安全信任的话,很可能会因为载入了有害的字节流而导致系统崩溃。验证阶段大致会完成4中不同的检验动作:

文件格式验证

文件格式验证主要是校验该字节流是否符合Class文件格式的规范,并且能被当前版本的虚拟机所接受。这个阶段包括但不限于以下验证点:

  • 是否以魔数0xCAFEBABE开头
  • 主、次版本号是否在当前虚拟机处理的范围之内
  • 常量池中是否有不支持的常量类型(通过tag校验)
  • 常量的索引是否有指向不存在或不符合类型的常量

元数据验证

元数据验证主要是对字节流中的描述信息(描述符)进行语义分析,以确保其描述的信息符合java语言规范的要求。这个阶段包括但不限于以下验证点:

  • 这个类是否有父类,除了java.lang.Object,所有的类都应该有父类
  • 这个类的父类是否继承了不允许被继承的类,如被final修饰的类
  • 如果这个类不是抽象类,是否实现了父类或接口中要求的所有的方法

字节码验证

字节码验证主要是对类的方法体进行分析,确保在方法运行时不会有危害虚拟机的事件发生。这个阶段包括但不限于以下验证点:

  • 操作数栈的数据类型与指令码中所需类型是否相符
  • 校验跳转指令是否会跳转到方法体以外的字节码指令上
  • 校验方法体中类型转换是否是有效的

符号引用验证

符号引用验证主要是对类自身以外的信息进行匹配新校验

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值