虚拟机类加载机制

1.概述
Class文件中描述的各种信息,最终都需加载到虚拟机后才能被运行和使用。
虚拟机类加载机制:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可被虚拟机直接使用的Java类型。
2.类加载时机
类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:
加载—>验证—>准备—>解析(此三部分统称为连接)—>初始化—>使用—>卸载。
!!只有加载、验证、准备、初始化和卸载五个阶段的顺序是确定的。
虚拟机规范严格规定*有且只有**4种情况(对类进行主动引用*),必须立即对类进行“初始化”(加载、验证、准备在此之前开始):
1)遇到new、getstatic、putstatic或invokestatic四条字节码指令时。如果类没有进行过初始化,则需先触发其初始化。(最常见:使用new实例化对象时、读取或设置一个类的静态字段(被final修饰、已在编译期把结果放入常量池的字段除外)的时候,及调用一个类的静态方法的时候)。
2)使用java.lang.reflect包的方法对类进行发射调用时,如果类没有进行过初始化,则先触发其父类初始化。
3)初始化一个类的时候,若发现其父类还没进行过初始化,则需先触发其父类的初始化。
4)虚拟机启动时,用户需指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。
被动引用:
!对于静态字段,只有直接定义这个字段的类才会被初始化,因此通过其子类来引用父类中定义的静态字段,只会触发父类的初始化而不会触发子类初始化。
!通过数组定义来引用类,不会触发此类的初始化。
!常量在编译阶段会存入调用类的常量池中,本质上没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化。
!!!当一个类在初始化时,要求其父类已经全部初始化了;但对于接口,并不要求其父类已经全部初始化,只在真正使用到父接口时(如引用父接口中常量)才会初始化。
3.类加载过程
3.1加载
此阶段,虚拟机完成3个过程:
1)通过一个类的全限定类名来获取定义此类的二进制字节流
2)将这个字节流所代表的静态存储结构转换为方法区的运行时数据结构
3)在Java堆中生成一个代表这个类的java.lang.Class对象,作为方法区这些数据的访问入口。
!!未指明二进制字节流的获取途径;
3.2验证
目的:确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并不会危害虚拟机自身安全。
大致会完成四个阶段的检验过程:
1)文件格式验证
以魔数0xCAFEBABE开头;主、次版本号是否在当前虚拟机处理范围内;常量池中是否有不被支持的常量类型(检查常量tag标志)…….
!!保证输入的字节流能正确的解析并存储于方法区之内,格式上符号描述一个Java类型信息的要求。
2)元数据验证
这个类是否有父类;父类是否继承了不允许被继承的类(final修饰)……
3)字节码验证
!!对类的方法体进行校验分析,主要是进行数据流和控制流分析。
4)符号引用验证
发生在虚拟机将符号引用转化为直接引用时。
主要验证:符号引用中通过字符串描述的全限定名是否能找到对应的类;指定类中是否存在符号方法的字段描述符及简单名称所描述的方法和字段……
!!若所用全部代码都已被反复使用和验证过,在实施阶段可以考虑使用-Xverify:none参数来关闭大部分类验证措施,以缩短虚拟机类加载时间。
3.3准备
正式为类变量分配内存并设置类变量初始值阶段,这些内存都将在方法区中进行分配。(!!实例变量将会在对象实例化时随对象一起分配在Java堆中)
3.4解析
虚拟机将常量池内符号引用替换为直接引用的过程。
解析动作主要针对类或接口、字段、类方法、接口方法四类符号引用进行。
3.5初始化
初始化阶段是执行类构造器<clinit>() 方法的过程。
<clinit>() 由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static{})中的语句合并产生的。 <clinit>()与类的构造函数(实例构造器<init>()方法)不同,不需显示调用父类构造器,虚拟机会保证在子类的 <clinit>() 执行前,父类 <clinit>() 已执行完毕。
!!执行接口的 <clinit>() 不需先执行父接口的 <clinit>()
4.类加载器
4.1类和类加载器
对任意一个类,都需由加载它的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性。
4.2双亲委派模型
这里写图片描述
4.3破坏双亲委派模型
线程上下文类加载器。
OSGI实现模块化热部署的关键是它自定义的类加载器机制的实现。每个程序模块(Bundle)都有自己的类加载器,当需更换一个Bundle时,就把Bundle连同类加载器一起换掉来实现代码的热替换。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值