运行时数据区
类生命周期
类加载器
类加载器负责装入类,搜索网络、jar、zip、文件夹、二进制数据、内存等指定位置的类资源。
一个java程序运行,最少有三个类加载器实例,负责不同类的加载。
验证问题
查看类对应的加载器
public class TestCollection {
public static void main(String[] args) throws Exception {
// 加载核心类库的BootStrap ClassLoader
System.out.println("核心类库加载器:"
+ TestCollection.class.getClassLoader()
.loadClass("java.lang.String").getClassLoader());
// 加载拓展类库的Extension ClassLoader
System.out.println("拓展类库加载器:"
+ TestCollection.class.getClassLoader()
.loadClass("com.sun.nio.zipfs.ZipCoder")
.getClassLoader());
// 加载应用程序库的
System.out.println("应用类库加载器:" + TestCollection.class.getClassLoader());
// 双亲委派模型 Parents Delegation Model
System.out.println("应用程序库加载器的父类:"
+ TestCollection.class.getClassLoader().getParent());
System.out.println("应用程序库加载器父类的父类:"
+ TestCollection.class.getClassLoader().getParent()
.getParent());
}
}
运行结果:
JVM如何知道我们的类在何方
class信息存放在不同的位置,桌面jar、项目bin目录、target目录等等
查看openjdk源代码:sun.misc.Launcher.AppClassLoader
结论:读取java.class.path配置,指定去哪些地址加载类资源
验证过程:利用jps、jcmd两个命令
1、jps 查看本机 JAVA进程
2、查看运行时配置:jcmd 进程号 VM.system_properties
类不会重复加载
类的唯一性:同一个类加载器,类名一样,代表是同一个类。
识别方式:ClassLoader Instance id + PackageName + ClassName
验证方式:使用类加载器,对同一个class类的不同版本,进行多次加载,检查是否会加载到最新的代码。
类的卸载
类什么时候会被卸载?
满足如下两个条件:
1、该Class所有的实例都已经被GC;
2、加载该类的ClassLoader实例已经被GC;
验证方式:jvm启动中增加 -verbose:class 参数,输出类加载和卸载的日志信息。
双亲委派模型
保证不会重复加载,安全
热加载:使用多个类加载器,进行加载