java类的生命周期是从class文件到加载到内存中的类,到类卸载出内存为止,整个周期包含了从加载到消亡的七个过程,具体类加载过程有如下几步:加载 > 验证 > 准备 > 解析 > 初始化 > 使用 > 卸载**
1.Loading(加载)
加载,就是将字节码文件加载到机器内存中,JVM将字节码文件中解析出来的常量池、类方法等存分别存放在JVM的各个内存区域,这样JVM在运行期间可以通过对应方法的引用获取到类中的任意信息、遍历成员变量、方法调用。例如调用类的main()方法,new对象等等,在加载阶段会在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。反射机制也基于这个。
知识点:类加载器 和 双亲委派机制
2.Verification(验证)
校验字节码文件的正确性,校验字节码在语义上是符合规范等。比如class必须是cafe babe开头的(cafe babe作为魔数的过程有一个故事,可以自行搜索一下)。
3.Preparation(准备)
给类的静态变量分配内存,并赋予默认值。
比如:
public static int initData=666; #给initData赋默认值为0
public static User user= new User(); #给user对默认象赋值为null
注意:
这里只会给static修饰的变量赋值。
基本数据类型和string通过字面量的方式,都是在准备环节进行显示赋值;
被final修饰静态变量会直接赋值,比如:
public static flnal int initData=666; #给initData赋值为666
4.Resolution(解析)
将符号引用替换为直接引用,该阶段会把一些静态方法(符号引用,比如main()方法)替换为指向数据所存内存的指针或句柄等(直接引用),这是所谓的静态链接过程(类加载期间完成),动态链接是在程序运行期间完成的将符号引用替换为直接引用。动态连接
如图,通过jclaaalib工具可以看到math类中的main方法引用常量池的第17行。
5.Initialzation(初始化)
1. 对的静态量初始化为指定的值;
比如:
准备(Preparation)阶段给initData赋值为0,在当前初始化阶段执行为666.
public static int initData=666; #给initData赋值为666
2. 执行静态代码块。
注意:父类方法的静态变量赋值和静态代码块执行 > 子类静态变量赋值和静态代码块。
知识点:初始化阶段代码的执行顺序
6.Using(使用)
在程序中调用类的静态方法、静态成员变量了。
7.Unloading(卸载)
如果程序运行过程中,堆中类的class对象不再被引用,方法区中的二进制数据会被卸载,称为类卸载。