美文网首页JVM笔记
7.虚拟机类加载机制

7.虚拟机类加载机制

作者: 雪关马不前 | 来源:发表于2019-11-24 13:14 被阅读0次

    虚拟机如何加载Class文件?

    Class文件中的信息进入到虚拟机后会发生什么变化?

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

    在Java语言里面,类型的加载、连接和初始化过程都是在程序运行期间完成的。

    类加载的时机

    类从被加载到虚拟机内存开始,到卸载出内存为止,它的正规生命周期包括:加载(loading),验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)7个阶段。 

    加载:

    Java虚拟机规范中并没有强制约束,由虚拟机的具体实现来把握。在加载阶段,虚拟机需要完成以下3件事:

    通过一个类的全限定名来获取定义此类的二进制字节流。

    将这个字节流所代表的的静态存储结构转化为方法区的运行时数据结构。

    在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

    验证

    主要的4个阶段的检验动作:文件格式验证、元数据验证、字节码验证、符号引用验证。

    准备

    准备阶段是正式为类变量分配内存地址设置变量初始值的阶段,这些变量所使用的内存都将在方法区中进行分配。这里的进行内存分配仅包括类变量(被static修饰的变量),而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在Java堆中。

    //在准备阶段过后value的初始值为0而不是123因为此时还未开始执行任何Java方法,而把value赋值为123的putstatic指令是程序被编译后。publicstaticintvalue=123;

    特殊情况

    //编译时javac将会为value生成ConstantValue属性,在准备阶段虚拟机就会根据ConstantValue的设置将value赋值为123publicstaticfinalintvalue=123;

    解析

    解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。 

    符号引用:以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可。

    直接引用:可以是直接指向目标的指针、相对偏移量或是一个能简洁定位到目标的句柄。直接引用时和虚拟机实现的内存布局相关的,同一个符号引用在不同的虚拟机实例上翻译出来的直接引用一般不会相同。如果有了直接引用,那引用的目标必定已经在内存中存在。

    类或接口的解析

    字段解析

    类方法解析

    接口方法解析

    初始化

    遇到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果类没有初始化则需要线触发其初始化。生成这4条指令的最常见的Java代码场景是:使用new关键字实例化对象的时候、读取或设置一个类的静态字段(被final修饰、已在编译期就把结果放入常量池的静态字段除外)的时候,以及调用一个类的静态方法的时候。

    使用java.lang.reflect包的方法对类进行反射调用时候。

    当初始化一个类的时候,如果发现其父类还没进行过初始化,则需要先触发其父类的初始化。

    当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类)。

    当使用jdk1.7以上的动态语言支持是,如果一个java.lang.invoke.MethodHandle实例最后的解析结果为REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且方法句柄所对应的类没有进行过初始化。

    常量在编译阶段会存入调用类的常量池中,本质上没有直接引用到定义常量的类,因此不会触发初始化。

    相关文章

      网友评论

        本文标题:7.虚拟机类加载机制

        本文链接:https://www.haomeiwen.com/subject/mkjlwctx.html