一个类进入jvm后,它经历了什么?

一个类进入jvm后,它经历了什么?,第1张

前提思考:一个类什么时候进入jvm?

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虚拟机进程终止

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/719575.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-25
下一篇 2022-04-25

发表评论

登录后才能评论

评论列表(0条)

保存