JVM - 类的生命周期你了解吗?

我们知道java语言具有动态性,程序的结构和行为可以在运行时发生变化,而不是在编译时就固定下来,像反射、动态代理等技术都是动态性的体现,其是Java强大功能和庞大生态(如Spring、Hibernate等框架)的重要基石。而JVM类加载机制为这种动态性提供了可能性和执行的舞台。
Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析、初始化,最终形成可以被虚拟机直接使用的Java类型的过程称为虚拟机的类加载机制。与那些在编译时需要进行连接的语言(C/C++)不同,在java语言里面,类型的加载、连接和初始化过程都是在程序运行期间完成的,这样策略让java语言在进行提前编译时会面临额外的困难,也会让类加载时稍微增加一些性能开销,但却为Java应用提供了极高的扩展性和灵活性。

详解

类完整的生命周期包含七个阶段:加载(Loading)->验证(Verification)->准备(Preparation)->解析(Resolution)->初始化(Initialization)->使用(Using)->卸载(Unloading),其中验证、准备、解析三个阶段又合称为"连接(Linking)"。

加载

主要完成以下三项任务:
1、通过一个类的全限定名来获取定义此类的二进制字节流(Class文件);
2、将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构;
3、在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口;
JVM获取二进制字节流的来源非常灵活,可以从ZIP包(JAR/WAR/EAR)、网络、运行时计算生成(动态代理)、或其他文件(JSP)等渠道获取。

注意:数组类本身不通过类加载器创建,而是由JVM直接创建,但其元素类型最终还是要靠类加载器加载。

验证

是连接阶段的第一个子阶段。核心任务是:确保class文件的二进制字节流中包含的信息符合《Java虚拟机规范》的全部约束要求,保证这些信息是安全的,无害的,不会危害虚拟机的正常运行。主要有以下四个详细步骤:
1、文件格式验证:发生在字节流还未进入方法区时;验证字节流是否符合Class文件格式规范,并能被当前虚拟机处理。比如校验魔数、版本号、常量池、各种索引值等等。只有通过了这个阶段的验证,字节流才会被允许进入内存的方法区存储,后续验证都是基于方法区的存储结构进行,不再直接操作字节流;
2、元数据验证:对类的元数据信息进行语义校验,确保其符合《java语言规范》的要求;可以看作是对类本身的语法检查。例如检查类是否继承了不允许被继承的类、类中字段或方法是否和父类产生矛盾等等;
3、字节码验证:这是最复杂的一个阶段,通过数据流分析和控制流分析,确定程序语义是合法的、符合逻辑的。可以看作是对方法代码的逻辑检查。比如校验操作数栈数据类型与指令代码序列配合正确,不会出现在操作数栈放置了一个int类型的数据,使用时却按long类型来加载进本地变量表中等等。

由于字节码校验的高度复杂性,在JDK6之后,JVM在编译期使用了一种称为“类型推断”的技术来更多的辅助验证,同时将一部分验证工作推迟到运行期,由编译器完成,以提升性能。

4、符号引用验证:这个动作实际发生在解析阶段;可以看作是对类自身之外的外部信息进行匹配性校验,确保解析动作能够正常执行。比如校验符号引用中通过全限定名是否能找到对应的类、访问权限校验等;
验证阶段是一个极其严格的代码审核和安全审计的过程,它确保了只有“合法且安全”的代码才能在JVM中运行。但是又是非必须要执行的阶段,因为验证只有通过和不通过的区别,只要验证通过了,其后对程序运行就没有任何影响了,如果程序已经被反复使用验证过,可以考虑使用-Xverify:none参数来关闭大部分类验证措施,以缩短虚拟机类加载时间。

准备

是连接阶段的第二个子阶段。核心任务是:在方法区中为类的静态变量分配内存,并为其设置初始"零值"。比如一个整形静态变量,在准备阶段结束之后,其值为0。

对于同时被static和final修饰的常量,那么在准备阶段,会直接将其赋值为对应代码中的值,而不是零值;这是因为编译器会将常量的值存储在ConstantValue属性表中,JVM会直接读取这个属性表并直接赋值,这本质是一种优化,避免初始化阶段又重新赋值。

此时处理的是类变量,而不是方法体中的局部变量和实例变量。

各个类型的零值如下所示:

数据类型 零值
int 0
byte 0
short 0
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值