JVM 类加载机制

概述:class文件必须加载到虚拟机才可以执行。
把类的数据从class文件加载到内存,并对数据进行校验,转换解析
初始化,最终形成可以被java虚拟机直接使用的java类型。
与其他语言不同,java类的加载和连接是在程序的运行期间

类加载过程 :LVPRIUU
加载 - 验证 - 准备 - 解析 - 初始化 - 使用 - 卸载
验证 - 准备 - 解析 —->连接

正常情况下,第一步应该是加载,但是下面这些情况是必须先进行初始化的。
主动引用(有且仅有):
第一点:遇到new getstatic putstatic invokestatic
第二点:使用类的反射 java.lang.refelct
第三点:如果对一个类初始化的时候发现父类还没有被初始化,那么立即进行父类的初始化。
第四点:虚拟机启动的时候,用户需要指定一个要执行的主类,虚拟机会先对这个类进行初始化。
被动引用举例:
第一:对于静态字段,只有直接定义这个字段的类才会被初始化,子类引用父类的静态字段,只会初始化父类的静态字段。
第二:一个类调用里另外一个类的final类型的常量,不会引起被调用常量所属类的初始化。

接口的初始化的区别不同于类的就在于四个有且仅有的第三点,当一个子类接口被初始化的时候,父类接口不一定会被初始化,只有父类接口被使用的时候才会被初始化。并且接口里面不能用static语句。

加载:
1. 通过类的全限定名(也就是从最开始包的路径的一个绝对路径)获取此类的二进制字节流(由类加载器完成,是在JVM外部实现的)。
2. 将字节流所代表的静态存储结构转化为方法区(存放类加载信息,常量,静态变量,JIT编译后的代码)的运行时数据结构。
3. 在堆(存放对象实例 )区实例化一个这个类的java.lang.class对象,作为方法区的数据的访问入口。
验证(保证class文件的字节流包含的信息符合当前虚拟机的要求)
如果不符合则会抛出java.lang.VerifyError的错误。
1. 文件格式验证:是否以魔数0xACFEBABE开头;主次版本号;常量池的常量中的类型是否支持……
2. 元数据验证:这个类是否有父类;这个类有没有继承不能被继承的类(被final修饰);这个类是不是抽象类,是不是实现了父类或者接口的所有方法;类中的字段方法是否产生矛盾,比如覆盖父类的final字段,或者出现不符合规则的方法重载。
3. 字节码验证(数据的控制流和数据流的分析):比如,使操作数栈的数据类型与指令代码匹配(防止int类型数据加载到本地变量表中变成了int);保证跳转指令不会跳转到方法体意外的字节码指令上面。
4. 符号引用验证(确保解析动作正确执行,发生在符号引用转化为直接引用的时候):符号引用通过字符串描述的全限定名是否找到对应的类;在指定的类中是否存在符合方法的字段描述以及简单名称所描述的字段和方法。
准备:
为变量(仅仅包括类变量-被static修饰的,不包括实例化对象)在方法区分配内存。
解析:
将常量池里面的符号引用替换成直接引用的过程。
初始化:也就是执行类构造器()的过程。
类加载器:
自定义加载器-应用程序类加载器-扩展类加载器-启动类加载器

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值