JVM类加载

1、什么是虚拟机类加载机制?
虚拟机把描述类的数据的Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。
2、类加载的时机?
类从被加载的虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)7个阶段。如图所示:


加载、验证、准备、初始化和卸载这5个阶段的顺序是确定的,类的加载过程必须按照这种顺序按部就班地开始,而解析阶段则不一定:它在某些情况下可以在初始化阶段之后再开始,这是为了支持Java语言的运行时绑定(也称为动态绑定或晚期绑定)。以下陈述的内容都已HotSpot为基准。
虚拟机规范严格规定了有且只有5中情况必须立即对类进行初始化,而加载、验证、准备自然需要在此之前完成。
2.1 什么是加载?
"加载"是“类加载”过程的一个阶段,在加载阶段,虚拟机主要做3件事情:
   1、通过一个类的全限定名来获取定义此类的二进制字节流。
   2、讲这个字节流所代表的的静态存储结构化转化为方法区运行时的数据结构。
   3、在内存中生成一个代表这个类的Java.lang.Class对象,作为方法区这个类的各种数据的访问入口。
2.2 验证阶段的4个检查动作:
1、文件格式验证:第一阶段验证字节流是否符合Class文件格式的规范,并且能被当前版本的虚拟机处理,验证点包括:是否以魔数0xXAFEBABE开头、主次版本号是否在当前虚拟机处理范围内、常量池的常量中是都有不被支持的常量类型、指向常量的各种索引是都有指向不存在的常量或不符合类型的常量等。
2、 元数据验证:第二阶段对字节码描述的信息进行语义的分析,以保证其描述的信息符合Java语言的规范的要求,验证点:这个类是否有父类(除了java.lang.Object之外,所有的类都行该有父类)、这个类的父类是否继承了不允许继承的类(被final修饰的类)、如果这个类不是抽象类,是否实现了其父类或接口中之中要求实现的所有方法、类中的字段是否与父类产生矛盾(例如覆盖了父类的final字段,或者出现不符合规则的方法重载,例如方法的参数一致,但是返回值类型却不一致)
3、字节码验证:第三阶段是整个验证过程最复杂的一个阶段,主要目的是通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的。
4、符号引用验证:
3、什么时候开始初始化?
初始化:初始化过程即执行类中的静态初始化代码,构造器代码以及静态属性的初始化。
虚拟机规范严格规定了有且只有5种情况必须立即对类进行“初始化”(而加载、验证、准备自然需要在此之前开始):
1) 遇到newgetstaticputstaticinvokestatic这四条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。生成这4条指令最常见的Java代码场景是:使用new关键字实例化对象的时候读取或设置一个类的静态字段的时候(被final修饰、已在编译器把结果放入到常量池的静态字段除外),以及调用一个类的静态方法的时候
2) 使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
3) 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
4) 当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机要先初始化这个主类。
5) 当使用jdk 1.7 的动态语言支持时,如果一个java,lang.invoke.MethodHandle实例最后的解析结果为REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个方法的句柄所对应的类没有初始化,则需要先触发其初始化。
4、 初始化的顺序:
1) 初始化的顺序:在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量的定义散布于方法定义之间,他们仍然会在任何方法(包括构造方法)被调用之前得到初始化。
public class House {
Window w1 = new Window(1);
public House() {
System.out.println("House()");
w3 = new Window(3_3);
}
Window w2 = new Window(2);
public void method() {
System.out.println("method()");
}
Window w3 = new Window(3);
public static void main(String[] args) {
House house = new House();
}
}
class Window {
Window(int order) {
System.out.println("window" + order);
}
}
//输出结果为:
window1
window2
window3
House()
window33
2) 静态数据的初始化:
静态初始化只有在必要的时候才进行,初始化的顺序是先静态对象(如果他们尚未因前面的对象创建过程而被初始化),而后是“非静态”对象。
 初始化过程: 
    1.父类静态; 
    2.子类静态; 
    3.父类普通–>父类构造方法结束 
    4.子类普通–>子类构造方法结束




5、类加载过程
类加载的全过程:加载、验证、准备、校验、初始化
加载是类加载过程的一个阶段。主要做三件事:
1) 通过一个类的全限定名来获取定义此类的二进制字节流。
2) 将这个字节流所代表的的静态存储结构转化为方法区的运行时数据结构。
3) 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。
    加载(简单理解为):装载过程负责找到二进制字节码并加载至JVM--即负责查找和导入class文件。
    验证:连接阶段的第一步,确保Class文件的字节流中包含的信息符合当前虚拟机的要求。
    准备:初始化装载类中的静态变量,给类的静态变量分配存储空间。
    解析:解析类中调用的接口,类,将符号引用转为直接引用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值