JVM类加载机制

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

        与哪些在编译时需要进行连接工作的语言不同,在Java语言里面,类型的加载和连接过程都是在程序运行期间完成的,这样会在类加载时稍微增加一下性能开销,但是却能为Java应用程序提供高度的灵活性,Java中天生可以动态扩展的语言特性就是依赖运行期动态和动态连接这个特点实现的。例如,如果编写一个使用接口的应用程序,可以等到运行时再指定其实际的实现。这种组装应用程序的方式广泛应用于Java程序之中。

        在实际情况中,每个Class文件都有可能代表着Java语言中的一个类或接口,而对于类和接口需要分开描述的场景会特别指明,Class文件并非指Class必须存在于具体磁盘中的某个文件,这里说的Class文件指的是一串二进制的字节流,无论以何种形式存在都可以。

       类从被加载到虚拟机内存中开始,到卸载出内存为止,它都生命周期包括来:加载、验证、准备、解析、初始化、使用和卸载七个阶段。其中验证、准备和解析三个部分统称为连接。这七个阶段的发生顺序如图所示。

          

       加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的,类的加载过程必须按照这种顺序按部就班地开始,而解析阶段则不一定:它在某些情况下可以在初始化阶段之后再开始,这是为了支持Java语言的运行时绑定称为动态绑定。这里说的“开始”而不是按部就班的“进行”或“完成”,因为这些阶段通常都是互相交叉地混合式进行的,通常会在一个阶段执行的过程中调用或激活另一个阶段。

       什么情况下需要开始类加载过程的第一个阶段:加载。虚拟机规范中并没有进行强制约束,这点可以交给虚拟机的具体实现来自由把握。对于初始化阶段,虚拟机规范则是严格规定了有且只有四种情况必须立即对类进行初始化。

       1)遇到new、getstatic、putstatic或invokestatic这4条字节码字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。

       2)使用java.lang.reflect包中的方法对类进行反射调用时,如果类没有进行过初始化,则需要先触发其初始化。

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

       4)虚拟机启动时,用户需要指定一个要执行的主类,虚拟机会初始化这个主类。 
---------------------
作者:柯之梦
来源:CSDN
原文:https://blog.csdn.net/yin4302008/article/details/86567393
版权声明:本文为博主原创文章,转载请附上博文链接!

原文地址:https://www.cnblogs.com/yinhongke/p/10297005.html