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

本文详细介绍了Java类加载的全过程,包括加载、验证、准备、解析和初始化等阶段,以及类加载的触发条件。在加载阶段,虚拟机获取类的二进制字节流并创建Class对象。验证阶段确保类的正确性,准备阶段为类变量分配内存并赋予默认值。解析阶段将符号引用转为直接引用。此外,讨论了类的卸载条件。
摘要由CSDN通过智能技术生成

前提思考:一个类什么时候进入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虚拟机进程终止

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值