1. 类的生命周期(类加载过程)
类加载的五个阶段:
- 加载(Loading):通过类的全限定名获取二进制字节流,生成Class对象
- 验证(Verification):确保字节码安全、符合JVM规范
- 准备(Preparation):为类的静态变量分配内存,并初始化为默认值
- 解析(Resolution):将符号引用转为直接引用(链接其他类)
- 初始化(Initialization):执行静态代码块、静态变量赋值
“准备阶段只赋默认值,初始化阶段才赋初始化值”。
2. 类加载器的分类
JVM提供了三种类加载器
1. 启动类加载器(Bootstrap ClassLoader):通过C/C++实现,负责加载Java核心类库,如jre的lib目录下的核心类。
2. 扩展类加载器(Extension ClassLoader):通过Java实现,对jre下lib/ext目录中的类库或者通过java.ext.dirs系统属性指定的路径的类库。
3. 应用程序类加载器(Application ClassLoader):就是我们写的程序、类。
除了上述三种类加载器,用户还可以通过继承java.lang.ClassLoader类的方式创建自己的类加载器,已实现特定需求。
3. 双亲委派模型
什么是双亲委派机制?为什么要用它?
- 定义:
在类加载器加载类时,会将请求交由父类加载器处理,只有在父类加载器无法完成时,才由当前加载器尝试加载。
JVM的类加载机制采用双亲委派模型。这个模型要求除了顶层的启动类加载器外,其余的类加载器都应有自己的父类加载器。类加载器在尝试自己去加载类时,首先会委托给父类加载器去完成,每个层次的类加载器都是如此,这样所有的类加载请求最终都会传送到顶层的启动类加载器中。如果父类加载器无法完成这个请求(它的搜索范围中没有找到所需的Class),子类加载器才会尝试自己去加载。 - 好处:
- 避免类的重复加载
- 保证核心类(如 java.lang.*)不被恶意篡改
- 哪些场景打破了双亲委派机制?
- Servlet容器、Springboot 自定义类加载器、SPI机制等…
4. 类的卸载与热加载
类会被卸载吗?哪些情况下类会被卸载?
- 类的卸载只会发生在满足以下条件:
- 该类所有对象都被回收
- 加载该类的 ClassLoader 也被回收
- Class对象本身不可达
JVM的类不会频繁卸载,web容器中热部署常见类卸载问题
5.类加载器命名空间隔离
不同的类加载器加载的相同类是同一个类吗?
不是。即使