Java八股文查漏补缺-JVM-2-类加载解析
0 写在前面
Java八股文查漏补缺系列是针对Java八股复习时,针对在面试时候,问的问题可能比较深入,在
JavaGuide
网站中的一些八股文可能不够用,根据自己的面试经验进行一些学习补充.八股文背不如理解,理解深刻,知道底层原理,才能更加牢固。呜呜!直接上题
本文目标:完善JVM类加载流程!
1. 类生命流程
- 加载
- 验证
- 准备
- 解析
- 初始化
- 使用
- 卸载
1 2 3 5按顺序,解析有可能在初始化后面,2 3 4 又称为连接
1.1 加载
干三件事!
- 全类名->字节流:通过类的全名获得它的对应的二进制字节流
- 字节流->方法区运行的数据结构:字节流所代表的静态存储结构转为方法区中的类的数据结构
- 方法区的数据结构->类的class对象:在堆中生成该类的class对象,作为对方法区的数据的访问入口
1.2 连接
验证:保证加载符合当前虚拟机要求
准备:为类的静态变量分配内存并且初始化为默认值,而不是程序员所期望的值(初始化才执行)
解析:虚拟机的常量池的符合引用替换为直接引用
1.3 初始化
为类的静态变量赋予正确的初始值
1.4 使用
1.5 卸载
- 执行了
System.exit()
方法 - 正常介数
- 异常或者错误
- os错误
2. 类加载器
2.1 结构
这里采用的不是继承,是组合!
分类
- 从JVM角度:只有启动类加载器(cpp实现)与其他(java实现)
- 从开发人员角度:
- 启动类加载器:加载
jdk/jre/lib
下面,所有以java.*
开头的类 - 扩展加载器:加载
jdk/jre/lib/ext
下面,所有以javax.*
开头的类 - 应用类加载器:加载用户类路径指定的类
- 启动类加载器:加载
加载机制(双亲委派)
加载类让上级先加载,验证类是否加载自己先验证
好处:
- 类加载层次清晰
- 避免类的重复加载
- 保证安全
双亲委派模型保证了 Java 程序的稳定运行,可以避免类的重复加载(JVM 区分不同类的方式不仅仅根据类名,相同的类文件被不同的类加载器加载产生的是两个不同的类),也保证了 Java 的核心 API 不被篡改。
双亲委派机制的打破
重写 loadClass()
方法,就可以改变传统双亲委派模型的执行流程。
Tomcat 服务器为了能够优先加载 Web 应用目录下的类,然后再加载其他目录下的类,就自定义了类加载器
WebAppClassLoader
来打破双亲委托机制。这也是 Tomcat 下 Web 应用之间的类实现隔离的具体原理。