【JVM笔记】类加载过程
类加载时机
加载—>验证—>准备—>解析—>初始化—>使用—>卸载
验证、准备、解析为连接阶段。
加载、验证准备、初始化和卸载这个阶段顺序是确定的。
加载
加载是类加载过程的一个阶段,这个过程中,虚拟机需要完成以下3件事。
- 通过一个类的全限名来获取定义此类的二进制字节流
- 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
- 在内存中生成一个代表这个类的Java.lang.Class对象,作为方法区这个类的各种数据的访问入口
验证
验证是连接阶段的第一步,它确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。有4个阶段的检验动作。
- 文件格式验证 Class文件格式的规范
- 元数据验证 语义分析
- 字节码验证 确定程序语义是合法、符合逻辑
- 符号引用验证 确保解析动作能正常执行
可以通过-Xverify:none参数关闭大部分类验证措施,以缩短虚拟机类加载时间。
准备
正式为类变量(仅指静态变量)分配内存并设置类变量初始值的阶段,这些变量使用的内存都将在方法区中进行分配。
解析
符号引用以一组符号来描述所引用的目标,符号可以任何形式的字典量,只要使用时能无歧义地定位到目标即可。不一定已经加载到内存中。
直接引用可以是直接指向目标的指针、相对偏移量或是一个能间接定位到目标的句柄。有了直接引用,那么引用目标必定已在内存中。
解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。主要针对 类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符 7类符号引用进行。
初始化
真正开始执行类中定义的Java程序代码(或者说是字节码)。
在准备阶段,变量已经赋过一次系统要求的初始值,而在初始化阶段,则根据程序员通过程序制定的主观计划去初始化类变量和其他资源,或者可以从另外一个角度来表达:初始化阶段是执行类构造器< clinit>()方法的过程。