今天遇到一个面试题,类的加载过程,感觉自己回答的一团糟,完全没有概念,那我今天还是一定要把这个整理一下
看下流程图(结构化思维)
5个大阶段:
加载--》链接--》初始化--》使用--》卸载
7个小阶段:(链接1拆3)
加载--》验证--》准备--》解析--》初始化--》使用--》卸载
①加载
JVM把class字节码加载到内存,将这些字节码转化成方法区中的运行时数据(静态变量,静态代码块,常量池等)
在堆中生产一个class的对象,通过反射机制,通过这个对象可以访问到方法区对应的数据
②链接(验证,准备,解析)
验证:确保加载的类信息符合jvm规范,没有安全方面的问题
准备:为类变量(static)生成内存空间,并设置初始值(只是设置初始值,区别一下初始化阶段做的事)
解析:常量池中的符号引用改为直接引用(地址引用),主要包括四种类型引用的解析。类或接口的解析、字段解析、方法解析、接口方法解析。
解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。
二者之间的关联如下
符号引用(Symbolic Reference):符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义的定位到目标就行,符号引用与虚拟机的内存布局没有关系,引用的目标不一定需要已经加载到内存中。种种虚拟机的内存布局可以都不相同。但是他们能接受的符号引用必须是一致的。符号引用的字面量形式明确定义在JAVA虚拟机规范的Class文件中。
直接引用(Direct Reference):直接引用是直接指向目标的指针、相对偏移量或是一个能间接定位到目标的句柄。直接引用是和虚拟机实现的内存布局相关的,同一个符号引用在不同虚拟机实例上翻译出来的直接引用一般不会相同,如果有了直接引用,那引用的目标必定在内存中存在。
③初始化
执行类构造器<clinit>的过程。
类构造器<clinit>方法是由编译器自动收集类变量的赋值动作和静态语句块中的语句合并生成的代码块。
注意:
a.如果发现父类没有初始化,先初始化父类
b.虚拟机会保障<clinit>在多线程下正确的加锁和同步
网友评论