Java虚拟机类的加载机制

一.类的生命周期

类的生命周期从类加载到虚拟机中内存,到卸载出内存为止。
在这里插入图片描述

二.类加载的过程

类加载的全过程:加载——验证——准备——解析——初始化
1.加载
类的加载阶段就是由类加载器负责根据类的全限定名来读取该类的.class文件中二进制数据读到JVM中,并存储在方法区中,在堆区中创建java.lang.Class对象,用来封装类在方法区中的数据结构,其实就是Java程序的中的类和接口。如果要获取该类的信息,就可以用过Class对象来调用系统提供的Class方法来访问。(Class client=Client.class)
链接阶段:链接阶段要做的是将加载到JVM中的二进制字节流的类数据信息合并到JVM的运行时状态中,包括验证——准备——解析三个阶段
2.验证
链接阶段的第一阶段就是验证,这一阶段的目的就是为了验证Class文件字节流中包含的信息符合JVM的要求,并且不会危害虚拟机自身的安全。
大致完成4个阶段的检验动作:文件格式验证、元数据验证、字节码验证、符号引用验证。
3.准备
正式为变量分配内存并设置类变量初始值阶段。这些变量使用的内存都在方法区分配,这个时候在内存中分配的仅包括类变量(static修饰的),不包括实例变量,实例变量会随着对象实例化一起在堆中分配内存,这里的赋初值通常是零值。
4.解析
解析阶段是将虚拟机常量池内的符号引用替换为直接引用的过程。

符号引用:符号应用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时无歧义地定位到目标即可,与虚拟机实现的内存布局无关,引用的目标并不一定以及加载到内存中。

直接引用:直接引用可以直接指向目标的指针、相对偏移量或是一个能间接定位到目标的句柄。直接引用是和虚拟机实现的内存布局相关的。引用的目标必定已存在于内存中。

在16个用于操作符号引用的字节码指令之前,先对它们所使用的符号引用进行解析。所有虚拟机实现可以根据需要来判断到底是在类被加载器加载时就对常量池中的符号引用进行解析,还是等到一个符号引用将要被使用之前才去解析它。

解析动作主要针对类或接口、字段、类方法、方法类型、方法句柄和调用点限定符7类符号引用进行解析。
  5.初始化
Java虚拟机只有在程序首次主动使用一个类或接口时才会去初始化他。只有当程序访问的静态变量或静态方法的确在当前类或接口中定义时,才是主动使用。
将一个类中所有被static关键字标识的代码统一执行一遍,如果执行的是静态变量,那么就会使用用户指定的值覆盖之前在准备阶段设置的初始值;如果执行的是static代码块,那么在初始化阶段,JVM就会执行static代码块中定义的所有操作。
所有类变量初始化语句和静态代码块都会在编译时被前端编译器放在收集器里头,存放到一个特殊的方法中,这个方法就是方法,即类/接口初始化方法。该方法的作用就是初始化一个中的变量,使用用户指定的值覆盖之前在准备阶段里设定的初始值。

三.类加载器

类加载器负责将类的.class文件加载到内存,并为之生成Java.lang.Class对象,一个载入jvm的类也有一个唯一的标识,其全限定类名和类加载器作为唯一标识
在JVM启动的时候,会形成由三个类加载器组成的初始类记载器层次结构
1、Bootstrap ClassLoader:根类加载器
2、Extension ClassLoader:拓展类加载器
3、System ClassLoader:系统类加载器
Bootstrap ClsaaLoader被称为根类加载器,它负责加载java类的核心类
Extension ClassLoader是拓展类加载器,负责加载JRE的拓展目(%JAVA_HOME%/jre/lib/ext或者由java.ext.dirs系统属性指定的目录)中JAR包的类,通过这种方式,就可以为java拓展核心类以外的新功能,只要把自己开发的类打包成JAR文件然后放入JAVA_HOME/jre/lib/ext路径即可。
System ClassLoader,系统类或者应用类加载器,它负责在JVM启动时加载来自java命令的-classpath选项、java.class.path系统属性,或CLASSPATH环境变量所指定的JAR包和类路径。

四.类加载器加载机制

全盘负责
当一个类加载器负责加载某个Class时,该Class所引用,和依赖的其他类也由该类加载器负责载入
双亲委托模型,约定类加载器的加载机制
先让父类加载器试图加载该Class,只有在父类加载器无法加载该类时才试图从自己的路径中加载该类。
使用双亲委托机制的好处是:能够有效确保一个类的全局唯一性,当程序中出现多个限定名相同的类时,类加载器在执行加载时,始终只会加载其中的某一个类。
缓存机制
缓存机制将会把之前加载过的Class都缓存起来,当程序需要某个Class时,先从缓存区加载该类,只有当缓存区不存在该Class对象时,系统才会读取该类的二进制数据,然后创建Class对象,存到缓存区。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值