架构图
加载(Loading)
“加载”是“类加载”过程的一个阶段,在加载阶段,虚拟机要完成以下三件事:
1.
通过一个类的全限定名获取定义此类的二进制字节流;
2.
将这个字节流所代表的的静态存储结构转化为
方法区
的运行时数据结构;
3.
在内存中生成一个代表此类的
java.lang.Class
对象,作为方法区这个类的各种数据的访问入口;
类加载的方式有以下几种:
1.
从本地文件系统直接加载;
2.
从网络中获取。比如
Web Applet
;
3.
从
zip
压缩文件中读取,比如
jar
包,
war
包;
4.
运行时计算生成,比如动态代理技术;
5.
由其它文件生成,比如
JSP
应用;
6.
从数据库提取
class
文件,很少见;
7.从加密文件中获取;
验证(Verification)
验证是连接阶段的第一步,这一阶段的目的是为了确保Class文件包含的信息符合当前虚拟机要求,并且不会危害虚拟机自身安全,通常来讲验证阶段会完成下面四个阶段的校验动作:
1.
文件格式验证:是否以魔数开头、主次版本号是否在当前虚拟机处理范围内、检查常量
tag
标志、
Class
文件中各个部分是否缺失或被修改
………
(
Unsupported
major.minor
version 52.0
)
2.
元数据验证:这个类是否有父类、这个类的父类是否继承了不被允许的类、类中的字段方法是否与父类矛盾
………..
3.
字节码验证:分析数据流和控制流,确保程序的语义是合法的、符合逻辑的;
4.
符号引用验证:确保解析动作能正常执行,如果无法通过符号引用验证,见抛出异常,常见的异常有
NoSuchFieldError
,
NoSuchMethodError
。
准备(Prepare)
准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区内分配。
解析(Resolve)
解析阶段是虚拟机将常量池中的符号引用替换为直接引用的过程,解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法类型和调用点限定符7类符号引用进行。
初始化(Initialization)
初始化阶段是类加载过程中的最后一步,初始化阶段才真正开始执行类中定义的逻辑。