JVM加载class文件的原理机制

萝らか妹 提交于 2020-01-29 03:40:27

Java的编译和平台独立性  

首先Java是平台独立性语言(C/C++就不是,java一次编译在各个平台上都能执行),这关键就在它的"字节码"和JVM机制。Java程序编译后不是直接生成硬件平台的可执行代码,而是生成.class的字节码文件,再交由JVM翻译成对应硬件平台可执行的代码。(也就是说.java文件被javac指令编译为.class的字节码文件,再由JVM执行)。

  Java字节码的执行分为:即时编译和解释执行,通常采用解释执行方式。解释执行是指解释器通过每次解释并执行一小段代码来完成.class程序的所有操作。即时编译则是将.class文件翻译成机器码在执行。

类的加载机制

  Java语言是一种具有动态性的解释性语言,类(Class)只有被加载到JVM中在能运行。

  JVM会将编译生成的.class文件加载到内存中,并组织成为一个完整的Java程序。  这个加载过程则是由类加载器(ClassLoader和它的子类)来完成的,其实质是把类文件从硬盘读到内存中。

  类的加载方式分为:

    (1)隐式加载:程序使用new等方式创建对象,会隐式的调用类加载器。

    (2)显式加载:直接调用class.forName()方法

  在Java中类的加载是动态的,它不会一次性记载所有类然后运行,而是先把保证程序能运行的基类先加载到JVM中,其他类则是在需要时再加载,这样就加快了加载速度,而且节约了程序运行过程中内存的开销。

 

  类的加载主要分为3步:

    1)装载。根据查找路径找到相应的class文件,然后倒入。

    2)链接。①检查:检查待记载的class文件的正确性。

          ②准备:给类中的静态变量分配存储空间。(这里用到了static关键字的知识)

         (3)解析:将符号引用转换成直接引用(此步是可选的)

    3) 初始化。对静态变量和静态代码块执行初始化工作。这个阶段才是真正开始执行类中的字节码。

  

  什么时候需要对类进行初始化?
    1)使用new该类实例化对象的时候;
    2)读取或设置类静态字段的时候(但被final修饰的字段,在编译器时就被放入常量池的静态字段除外static final);
    3)调用类静态方法的时候;
    4)使用反射Class.forName(“xxxx”)对类进行反射调用的时候,该类需要初始化;
    5) 初始化一个类的时候,有父类,先初始化父类(注:1. 接口除外,父接口在调用的时候才会被初始化;2.子类引用父类静态字                        段,只会引发父类初始化);
    6) 被标明为启动类的类(即包含main()方法的类)要初始化;
    7)当使用JDK1.7的动态语言支持时,如果一个java.invoke.MethodHandle实例最后的解析结果REF_getStatic、REF_putStatic、                        REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化。

  类加载器:

    类加载器实现的是类的加载动作。比较两个类是否“相等”(类的equals、isInstance方法等),只有两个类由同一个加载器加载的前提下才有意义。

   (*)加载模型:双亲委派模型(*):

      从JVM角度将,只存在两种类加载器,一种是启动类加载器(Bootstrap ClassLoader),另一种是其他类加载器。他们都是继承ClassLoader类的。

    双亲委派模型中类加载器之间是有层次关系的如下图:

    

       模型要求除了顶层的启动类加载器外,其余类加载器都要有自己的父类加载器(父子两个是使用组合关系复用父类加载器代码,一般不是继承)

     **模型的工作过程:如果一个类加载器收到加载请求,他首先不会自己取尝试加载这个类,而是把这个请求委派给父类去完成,因此所有的记载请求最终都应该传送到顶层的启动类加载器中。只有父类加载器的搜索范围没有找到所需的类时,子类才会尝试自己加载。 

     这种工作模式是的Java类随加载器一起具备的优先级的层次关系。如果没有双亲委派,由各个类加载器自行加载的话,如果用户自己编了一个叫lang.Object的类,并放到ClassPath中,那用户将会出现多个不同的Object类,会导致程序混乱。

 

  

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!