【JVM】类加载机制
概念
类加载机制:JVM把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型
- 类型的加载、连接、初始化都是在程序运行期间完成,增加了性能开销,提高了灵活性
- 每个Class文件代表类或接口
- 在JVM中Class文件是一串二进制的字节流
类加载步骤
类从加载到内存到使用完卸载,需要经历 加载 - 连接(验证、准备、解析) - 初始化 - 使用 - 卸载
加载
获取:通过类的全限定名获取定义此类的二进制字节流
转化:将字节流代表的静态存储结构转化为方法区的运行时数据结构
生成对象:在内存中生成一个代表这个类的java.lang.Class对象,作为这个类访问入口
验证
文件格式验证:验证字节流是否符合Class文件格式规范,并且能被当前JVM处理
元数据验证:对字节码描述信息进行语义分析,保证描述信息符合Java语言规范
字节码验证:通过数据流和控制流分析,确定程序语义是合法且符合逻辑的
符号引用验证:对类自身以外的信息进行匹配性校验,确保解析动作能正常执行
准备
为类变量在方法区分配内存(指static变量,实例变量在java堆中)
为类变量设置初始值(为0值,具体赋值在初始化阶段)
解析
将常量池内的符号引用替换为直接引用的过程
- 符号引用:以一组符号描述所引用的目标
- 直接引用:直接指向目标的指针、相对偏移量、句柄
初始化
对准备阶段赋过的初始值 根据 java代码进行初始化
加载顺序为:静态变量(父-子) - 静态代码块(父-子)- 匿名代码块(父) - 构造函数(父) - 匿名代码块(子) - 构造函数(子)
类加载器
作用
加载class:类加载的加载阶段的获取就是通过类加载器实现的
确定类的唯一性:对于每一个类,需要加载器和这个类本身共同确定类在JVM中的唯一性
分类
启动类加载器:负责加载
JAVA_HOME\lib
目录或被-Xbootclasspath
参数指定目录中的部分类扩展类加载器:负责加载
JAVA_HOME\lib\ext
目录或被java.ext.dirs
系统变量指定路径中的所有类库应用程序类加载器:负责加载用户类路径上的类(如果没有自定义类加载器,应用程序类加载器就是程序默认的类加载器)
自定义类加载器:加载指定目录的类
双亲委派模型
工作过程:
- 一个类加载器收到了类加载的请求
- 该加载器把这个请求委派给它上一层的父加载器,每层如此
- 启动类加载器开始尝试加载类,若反馈无法完成,子加载器尝试自己去加载
好处:
- 让类跟类加载器一样有了“优先级”
- 对保证Java稳定运行至关重要
破坏双亲委派模型:
- JDK1.2之前的类加载器和抽象类java.lang.ClassLoader
- JNDI服务
- 代码热替换、模块热部署
参考:
https://blog.csdn.net/huyuyang6688/article/details/81490570
https://www.cnblogs.com/hadoop-dev/p/6907471.html