小目标之读懂JVM—虚拟机类加载机制

17 篇文章 0 订阅
13 篇文章 0 订阅

上一章讲述了Class文件信息存储格式,这一章讲述虚拟机如何加载Class文件。虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,就是虚拟机的类加载机制。

Java语言中,类型的加载、连接和初始化过程都是在程序运行期间完成的,这点实现了Java中动态扩展的语言特性。

类加载的生命周期包含加载、验证、准备、解析、初始化、使用和卸载7个阶段,其中验证、准备、解析3个部分统称为连接。

类加载的第一个加载阶段并未在虚拟机规范中进行强制约束,初始化阶段虚拟机则严格规定有且只有5种情况必须进行。1.遇到new、getstatic、putstatic、invokestatic这4条字节码指令时2.使用java.lang.reflect包方法反射调用时3.初始化一个类发现父类还未初始化时优先出发父类初始化4.虚拟机启动时的main方法所在的主类5.使用JDk1.7的动态语言支持时,java.lang.invoke.MethodHandle实例的解析结果REF_getStatic、REF_putStatic、REF_invokeStatic的方法具柄对应的类未进行初始化时。

加载阶段虚拟机需完成3件事情。1.通过类的全限定名获取对应的二进制字节流2.将字节流代表的静态存储结构转化为方法区的运行时数据结构3.内存中生成一个java.lang.Class对象,作为类的各种数据访问入口。类加载过程是开发人员可控性最强的,可以通过自定义类加载器控制字节流的获取方式

验证阶段是连接阶段的第一步,这一步是为了确保Class文件的字节流中的信息符合虚拟机要求,且不会危害虚拟机安全。大致分为4个检验动作。1.文件格式验证,主要是验证字节流是否符合Class文件格式的规范,保证字节流格式上符合Java类型信息的要求,能正确的解析并存储于方法区之内。2.元数据验证,主要是对字节码描述信息进行语义分析,以保证描述信息符合Java语言规范的要求。3.字节码验证,主要是对数据流和控制流分析,保证程序语义合法,符合逻辑。4.符号引用验证,主要是对类自身以外的符号引用进行匹配校验。这4个动作以一段英文语句进行对比的话就类似于1检验是否输入都是英语2检验是否符合英语语法规则3检验语句逻辑是否合理4检验名人名言的引用是否存在

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这时候分配的值仅包含类变量,且仅为变量类型对应的默认值,如int的默认值为0,Integer的默认值为null,public static int value=123在此处被分配的值为0,赋值为123的动作在初始化阶段才会执行。

解析是虚拟机将常量池内的符号引用替换为直接引用的过程,即是将表中小明的住址一栏直接替换为北京市朝阳区8号胡同6号,主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄、调用点限定符7类符号引用进行。

初始化是类加载的最后一步,初始化是根据程序员通过程序指定的主观计划去初始化类变量和其他资源,如之前提到的value=123在此阶段才被赋值为123.

最后的内容是对于类加载器的介绍,类加载器的功能是实现类加载阶段中的“通过一个类的全限定名来获取此类的二进制字节流”的动作,但是可让应用程序自己决定如何获取。Java程序中的类是否一致的定义是类加载器和对应的Class文件是否均一致。对于程序员来说类加载器可以划分为启动类加载器(BootStrap ClassLoader)、扩展类加载器(Extension ClassLoader)、应用程序类加载器(Application ClassLoader),启动类加载器用于加载<JAVA_HOME>\lib目录下的虚拟机可识别的类库,扩展类加载器加载<JAVA_HOME>\lib\ext目录下的所有类库,应用程序类加载器加载用户类路径(ClassPath)下指定的类库,之后用于还可以扩展自己的自定义加载器。整个路径为启动类->扩展类->应用程序类->用户自定义,从JDK1.2之后类加载器推荐采用双亲委派的模型,即类加载请求优先由父加载器加载,父加载器无法加载时再由本级的加载器进行加载。双亲委派模型在一些情况下会不适用,如JNDI需要基础类去调用厂商自定义的类时,还有在OSGI环境下代码热替换和模块热部署均可能会破坏双亲委派模式。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值