【JVM】类加载机制

概念

类加载机制:JVM把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型

  • 类型的加载、连接、初始化都是在程序运行期间完成,增加了性能开销,提高了灵活性
  • 每个Class文件代表类或接口
  • 在JVM中Class文件是一串二进制的字节流

 

类加载步骤

类从加载到内存到使用完卸载,需要经历 加载 - 连接(验证、准备、解析) - 初始化 - 使用 - 卸载

【JVM】类加载机制

加载
  1. 获取:通过类的全限定名获取定义此类的二进制字节流

  2. 转化:将字节流代表的静态存储结构转化为方法区的运行时数据结构

  3. 生成对象:在内存中生成一个代表这个类的java.lang.Class对象,作为这个类访问入口

验证
  1. 文件格式验证:验证字节流是否符合Class文件格式规范,并且能被当前JVM处理

  2. 元数据验证:对字节码描述信息进行语义分析,保证描述信息符合Java语言规范

  3. 字节码验证:通过数据流和控制流分析,确定程序语义是合法且符合逻辑的

  4. 符号引用验证:对类自身以外的信息进行匹配性校验,确保解析动作能正常执行

准备
  1. 为类变量在方法区分配内存(指static变量,实例变量在java堆中)

  2. 为类变量设置初始值(为0值,具体赋值在初始化阶段)

解析

将常量池内的符号引用替换为直接引用的过程

  • 符号引用:以一组符号描述所引用的目标
  • 直接引用:直接指向目标的指针、相对偏移量、句柄
初始化
  1. 对准备阶段赋过的初始值 根据 java代码进行初始化

  2. 加载顺序为:静态变量(父-子) - 静态代码块(父-子)- 匿名代码块(父) - 构造函数(父) - 匿名代码块(子) - 构造函数(子)

 

类加载器

作用
  • 加载class:类加载的加载阶段的获取就是通过类加载器实现的

  • 确定类的唯一性:对于每一个类,需要加载器和这个类本身共同确定类在JVM中的唯一性

分类
  • 启动类加载器:负责加载 JAVA_HOME\lib目录或被-Xbootclasspath参数指定目录中的部分类

  • 扩展类加载器:负责加载JAVA_HOME\lib\ext目录或被java.ext.dirs系统变量指定路径中的所有类库

  • 应用程序类加载器:负责加载用户类路径上的类(如果没有自定义类加载器,应用程序类加载器就是程序默认的类加载器)

  • 自定义类加载器:加载指定目录的类

双亲委派模型

工作过程:

  1. 一个类加载器收到了类加载的请求
  2. 该加载器把这个请求委派给它上一层的父加载器,每层如此
  3. 启动类加载器开始尝试加载类,若反馈无法完成,子加载器尝试自己去加载

好处:

  • 让类跟类加载器一样有了“优先级”
  • 对保证Java稳定运行至关重要

破坏双亲委派模型:

  • JDK1.2之前的类加载器和抽象类java.lang.ClassLoader
  • JNDI服务
  • 代码热替换、模块热部署

 

参考:
https://blog.csdn.net/huyuyang6688/article/details/81490570
https://www.cnblogs.com/hadoop-dev/p/6907471.html