Java类生命周期图
加载
- 通过一个类的全限定名来获取此类的二进制字节流
- 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
- 在java堆中生成一个代表这个类的Class对象,作为方法区这些数据的访问入口
连接
验证
- 验证是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全
- 包括文件格式验证、元数据验证、字节码验证、符号引用验证
准备
- 类变量分配内存,并设为jvm默认的初始值
解析
- 将常量池内的符号引用替换为直接引用的过程
- 主要针对类或接口、字段、类方法、接口方法四类符号引用进行解析
- 符号引用
- 以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可。符号引用与虚拟机实现的内存布局无关,引用的目标并不一定已经加载到内存中
- 直接引用
- 可以是直接指向目标的指针、相对偏移量或者一个能间接定位到目标的句柄。如果有了直接引用,那引用的目标必定已经在内存中存在。
初始化
- 初始化阶段是执行类构造器clinit方法的过程
- clinit方法
- 由编译器自动收集所有类变量(静态非final) 赋值操作和静态代码块语句合并产生
- 收集顺序由出现顺序决定,定义在前面的不能访问定义在后面的类变量
- 虚拟机保证父类clinit方法先于子类clinit方法执行
- 类或接口不一定都有clinit方法
- 虚拟机保证clinit方法在多线程环境下被正确的加锁和同步
- 时机
- new、操作该类类变量、调用类方法
- 对类反射
- 子类初始化的时候,父类还没有初始化,则会先进行父类初始化
- main函数对应的类
使用
参考对象生命周期
卸载
jvm回收条件
- 该类所有的实例都已经被回收
- 加载该类的ClassLoader已经被回收
- Class对象没有任何地方被引用,且无法在任何地方通过反射访问该类的方法
网友评论