JAVA虚拟机学习总结——类加载机制

虚拟机学习总结

类加载机制

虚拟机把描述类的信息从Class文件中加载到内存,并对数据进行校验,解析和初始化,最终形成可以被虚拟机直接使用的过程。
类型的加载,连接和初始化都是在运行期间完成的一运行期动态加载和动态连接。
类的生命周期:加载连接初始化使用-卸载,其中连接又包括:校验,准备和解析。其中,除了解析以外,其他阶段都是按部就班地“开始”(通常会在一个阶段执行的过程中调用,激活另一个阶段),而解析阶段有可能会在初始化之后(动态绑定)。

一、 加载

1.通过一个类的全限定名来获取此类的二进制文件流。
2.将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
3.在内存中生成一个代表这个类的class对象,作为方法区这个类的各种数据结构的访问入口,对于非数组类的加载,既可以使用引导类加载器完成,又可以使用用户自定义的类加载器完成。数组类本身不通过类加载器创建,而是通过虚拟机直接创建。

二、验证

确保class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。
1.文件格式验证:确保输入的字节流能正确地解析并存储于方法区之内,格式上描述符合一个Java类型信息的要求。
2.元数据的验证:对类的元数据信息进行语义校验,保证不存在不符合java语言规范的元数据信息。
3.字节码验证:通过对数据流和控制流进行分析,确保程序语义是合法的,符合逻辑的。
4.符号引用验证:确保解析动作能正常进行。

三、准备

正式为类变量在方法区分配内存并设置类变量初始值得阶段(零值)。

Public static int value= 123 //准备阶段后value值为0,初始化后为123
Public final static int value= 123 //准备阶段后value就为123

四、解析

四:解析。
解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。符号引用:以一组符号来描述引用的目标。直接引用:可以直接指向目标的指针,相对偏移量或是一个能间接定位到目标的句柄,
+ 类或接口的解析
+ 字段解析
+ 类方法解析
+ 接口方法解析

五、初始化

根据程序员通过程序制定的主观计划去初始化类变量和其他资源,就是执行类构造器clinit()方法.

clinit
  • clinit()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块合并产生的,编译器收集的顺序是由语句在源文件中出现的顺序决定的,静态语句块能给定义在其后面的语句块赋值,但不能访问。
  • clinit()方法与实例构造器不同的是,它不需要显示地调用父类构造器,但虚拟机会保证父类的clinit()方法已经执行完毕,所以父类中定义的静态语句块要优于子类的类变量赋值.
  • 如果没有静态语句块也没有对类变量的赋值操作,则不会产生clinit()方法.
  • 只有当接口中定义的变量在使用时,才会执行clinit()方法。执行子接口的clinit()方法或初始化接口的实现类都不会执行接口的clinit()方法.
  • 虚拟机会保证一个类的clinit()方法线程安全。
初始化的时机
主动引用(有且只有)
  • 使用new实例化对象,读取或设置一个类的静态字段(除了被final修饰,已在编译期间放入常量池的静态字段除外),调用一个类的静态方法。
  • 使用reflect对类进行反射调用,
  • 初始化一个类,要先初始化其父类
  • 启动虚拟机时运行包含main方法的那个类。
  • 当使用JDK1.7动态语言支持时,如果一个MethodHandle实例最后的解析结果是REF getStatic, REF putStatic, REFinvokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行初始化,则需要先进行初始化。
被动引用(不会触发其初始化)
  • 通过子类引用父类的静态字段,只会初始化父类,不会初始化子类。但是可能会加载子类,
  • 通过数组来定义引用类,不会触发此类的初始化。
  • 常量在编译阶段会存入此类的常量池中,本质上并没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化。
接口与类的区别

当一个类在初始化时,要求其父类都完成了初始化,但是在一个接口在初始化时,并不要求其父接口都完成了初始化,只有在使用父接口的时候才会进行初始化。

类与类加载器

对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在Java虚拟机中的惟一性,每一个类加载器,都拥有一一个独立的类名称空间。
+ 启动类加载器。加载JAVA_ HOME/lib目录中的,或者被Xbootclasspath参数指定的路径中,并且是虚拟机识别的。
+ 拓展类加载器。加载JAVA HOME/lib/ext或者被java.ext.dirs系统变量指定的路径中的所有类库。
+ 应用程序类加载器,是getSystemClassLoader的返回值,即系统类加载器,默认类加载器。

双亲委派模型

除了启动类加载器外,其余的类加载器都有自己的父类加载器,父子关系不是以继承的方式实现,而是以组合关系来复用父加载器的代码。
一个类加载器在收到类加载请求时,先交给父类加载器加载,父类加载器不能加载时,才会尝试自己加载。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值