本文章讨论:类装载子系统,涉及的加载过程如下:
1:加载阶段
2:链接阶段
3:初始化阶段
下面详细介绍该三个阶段:
一:加载阶段--loading
1:通过一个类的全限定名获取定义此类的二进制字节流
2:将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
3:在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据访问入口
补充:加载 .class 文件的方式:
- 从本地系统中直接获取
- 通过网络获取,典型场景:Web Applet
- 从zip压缩包中读取、成为日后从jar、war格式的基础
- 运行时计算生成,使用最多的是:动态代理技术
- 由其他文件生成,典型应用:JSP应用(JSP内可以写java代码)
- 从专用数据库中提取 .class 文件,比较少见
- 从加密文件中获取,典型的防Class文件类反编译的保护措施
二:链接阶段(分三个阶段:验证、准备、解析)
验证(Verify):
目的在于确保 Class 文件的字节流包含信息符合当前虚拟机要求,保证被加载类的正确性,不危害虚拟机自身安全
主要包括四种验证、文件格式、元数据验证、字节码验证、符号引用验证
准备(Prepare):
为类变量分配内存并且设置该类变量的默认初始值,即零值
这里不包含final修饰的static,因为final在编译的时候就会分配,准备阶段会显示的初始化
这里不会为实例变量分配初始化,类变量会分配在方法区中,而实例变量会随着对象一起分配到java堆中
解析(Resolve):
将常量池内的符号引用转换为直接引用的过程
事实上,解析操作往往会伴随着JVM在执行完成初始化之后在执行
符号引用就是一组符号来描述所引用的目标,符号引用的字面变量行驶明确定义在《java虚拟机规范》的Class 文件格式中,直接引用就是直接执行目标的指针,相对偏移量或一个简洁定位到目标的句柄
解析动作主要针对类或接口、字段、类方法、接口方法、方法类型等,对应常量池中的 CONSTANT_Class_info,Constant_Filedref_info、CONSTANT_Methodref_info等。
三:初始化阶段
扩展:类加载器的分类(加载阶段--》详细介绍三个加载器的传送门--传送门):