0
点赞
收藏
分享

微信扫一扫

JVM的类加载机制

余寿 2022-03-12 阅读 66

类加载流程

概述

类加载器的目的

  • 通过将编译后的字节码文件的加载,生成某种形式的与Class相关的数据结构存入内存,程序可以通过这个数据结构生成对应的object对象。这个过程是在运行时进行的,这也是java实现动态拓展的根基。

类的生命周期:

  1. javac编译为字节码文件
  2. 加载:在方法区中生成静态数据结构、在堆中生成便于用户调用的java.lang.Class类型的对象
  3. 链接:验证、准备、解析(注意解析是可以在初始化之后进行的,实现后期绑定,其他过程顺序不可变)
  4. 初始化
  5. 使用
  6. 卸载

加载

加载是整个类加载过程的第一个环节,它的主要目的在于通过.class的二进制流,在方法区中生成一个静态的数据结构,并在堆中生成一个java.lang.Class类型的对象以方便用户调用生成对应的实例化对象的过程。
在这里插入图片描述
这是一个但输入双输出的模型:

  • 输入:.class的二进制流,可以是本地文件、网络二进制流、数据库二进制流,甚至是计算出来的class,动态代理技术就是基于此,生成代理对象
  • **输出:**将二进制流的静态存储结构转换为方法区中的运行时存储数据结构
  • **输出:**可以被调用的java.lang.Class类型的对象,可以通过这个对象生成相应的object对象

链接

验证

总而言之就是对Class进行语法语义分析,保证其不危害虚拟机

  • 文件格式验证:验证字节流是否符合规范
  • 元数据验证:类的继承关系是否准确等
  • 字节码验证:确定程序语义正确
  • 符号引用验证:确定程序能正确运行

准备

为静态变量分类内存并赋0值,分配的内存在方法区。但如果是final关键字修饰的基本类型,那么就在准备阶段就赋值

解析

将符号引用转换为直接引用的过程。假设A引用了B,那么A中B的地址采用的是一个字符串进行存储,当加载A发现B没有被加载的时候会触发B的加载,并将字符串替换为B的地址,这就是一个符号引用转换为直接引用 的过程

  • 静态绑定:如果引用的是具体的实现类,能实现明确的直接引用。
  • 动态绑定:如果引用的是抽象类或者接口,接口可能有多个具体的实现类,无法明确具体的地址,那么就等一等,一直到运行过程中发生了调用,确定具体引用哪个实现类。这也是为什么解析阶段可以发生在初始化之后。

初始化

代码中是否有主动初始化变量的过程,有的话就执行。

卸载

自带类加载器不会被卸载,自定义的类加载器加载的类是可以被卸载的,满足三个条件

  • 该类所有实例被GC
  • 该类没有再被引用
  • 该类的类加载器的实例已经被GC

类加载器

举报

相关推荐

0 条评论