3个时间点会触发类加载
1. 虚拟机启动时,执行main()方法的时候
2. new一个对象的时候会触发类加载器
3. 读取静态字段或静态方法的时候
类进入jvm后的经历类从被加载到虚拟机内存中开始,到GC(垃圾回收)卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段。
其中,加载、验证、准备、初始化、卸载 这五个阶段发生的顺序是确定的,而解析阶段不一定,它在某些特殊情况下可以在初始化阶段之后。
另外,这7个阶段通常都是相互交叉的混合式进行的,通常会在一个阶段执行的过程中调用或激活另外一个阶段。
1. 加载“加载”是“类加机制”的第一个过程,在加载阶段,虚拟机主要完成三件事:
(1)通过一个类的全名(包名+类名)获取此类的二进制字节流
(2)讲这个字节流所代表的静态存储结构(存储格式,代码)和转化为方法区的运行时的数据结构(类信息)。
(3)在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。
2.验证验证Class文件的内容是否符合当前虚拟机要求,保证被加载类的正确性,不会危害虚拟机自身安全。主要包括四种验证:文件格式验证,源数据验证,字节码验证,符号引用验证。
3.准备为类变量分配内存并且设置该类变量的默认初始值,即零值;
不包含用final修饰的static(常量),因为final在编译阶段就会分配了,准备阶段会显示初始化;
不会为实例变量分配初始化,类变量会分配在方法区中,而实例变量是会随着对象一起分配到java堆中。
public class Hello(){
//类变量(静态变量):被分配在方法区中,在类加载的准备阶段初始值为0
public static int a=1;
//准备阶段,不处理,final在编译阶段就分配好了
public final static int b;
//实例变量:只会在堆中分配
public int c=1;
}
4.解析
将常量池内的符号引用转换为直接引用的过程。那问什么是符号引用、直接引用?
1.符号引用:一组符号来描述所引用的目标。符号引用的字面量形式明确定义在《java虚拟机规范》的Class文件格式中。
⒉.直接引用:直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。
举个栗子:
String str="abc"; //str 就是符号引用,abc就是目标
System.out.println(str); //打印引用符号
//经过编译后,直接变成:
System.out.println("abc"); //打印指针
5.卸载
卸载就是结束了类的生命周期。通常4种情况,导致卸载。
1.执行了System.exit()方法
⒉程序正常执行结束
3.程序在执行过程中遇到了异常或错误而异常终止
4.由于 *** 作系统出现错误而导致Java虚拟机进程终止
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)