赞
踩
目录
Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最 终形成可以被虚拟机直接使用的Java类型,这个过程被称作虚拟机的类加载机制。
今天要来介绍的就是如下同标识中的内容
一个类的加载需要经过 加载、验证、准备、解析、初始化、使用、卸载
如上图,加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的,类型的加载过程必须按 照这种顺序按部就班地开始,而解析阶段则不一定:它在某些情况下可以在初始化阶段之后再开始
加载过程中,Java虚拟机需要完成三件事情
① 通过一个类的全限定名来获取定义此类的二进制字节流
② 将这个字节流所代表的静态存储结构化转化为方法区的运行时数据结构
③ 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口
验证是连接阶段的第一步,这一阶段的目的是确保Class文件的字节流中包含的信息符合《Java虚 拟机规范》的全部约束要求,保证这些信息被当作代码运行后不会危害虚拟机自身的安全。
验证阶段大致上会完成四个阶段的检验动作:
文件格式验证:保证输入的字节流能正确地解析并存储于方法区之内,格式上符 合描述一个Java类型信息的要求。
元数据验证:主要对类的元数据信息进行语义校验,保证不存在与《Java语言规范》定义相 悖的元数据信息。
字节码验证:字节码验证阶段是整个验证过程中最复杂的一个阶段,主要目的是通过数据流分析和控制流分析,确定 程序语义是合法的、符合逻辑的。
符号引用验证:符号引用验证可以看作是对类自身以外(常量池中的各种符号 引用)的各类信息进行匹配性校验,通俗来说就是,该类是否缺少或者被禁止访问它依赖的某些外部 类、方法、字段等资源
准备阶段是正式为类中定义的变量(即静态变量,被static修饰的变量)分配内存并设置类变量初始值的阶段,初始值也就是0值(0,null,false)
注意:这里的赋予初始值指的是静态的变量,这里不包括Final修饰的静态变量,因为Final修饰的变量就视为常量了,Final在修饰的时候就会分配了,准备阶段是显式初始化,常量应是什么值,这里就直接赋予什么值。
解析阶段是Java虚拟机将常量池内的符号引用替换为直接引用的过程。
之前介绍的几个类加载的动作里,除了在加载阶 段用户应用程序可以通过自定义类加载器的方式局部参与外,其余动作都完全由Java虚拟机来主导控制。直到初始化阶段,Java虚拟机才真正开始执行类中编写的Java程序代码.
在初始化阶段,虚拟机会完成以下几件事:
① 初始化阶段就是执行类构造器<clinit>()方法的过程。<clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static{}块)中的语句合并产生的。编译器收集的顺序是由语句在源文件中出现的顺序决定的。
②Java虚拟机会保证在子类的<clinit>()方法执行前,父类的<clinit>()方法已经执行完毕。因此在Java虚拟机中第一个被执行的<clinit>()方法的类型肯定是java.lang.Object。
③Java虚拟机必须保证一个类的<clinit>()方法在多线程环境中被正确地加锁同步。
参考文献:《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)》
好了,这次的文章就到这里,喜欢的同学可以点赞收藏,遇到问题,可以评论,或者留言,我一定会第一时间给到回馈,感谢观看!!
注:本文为本人学习时心得分享,有讲错或者需要改正的地方,请指正,我会虚心接受
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。