zoukankan      html  css  js  c++  java
  • JVM虚拟机系列(一)类的加载

    JAVA虚拟机系列(一) 类的加载

    目录

     1 类的初始化过程

     2 详解初始化时的各个阶段

    一、类初始化的过程

    先来看一个CLASS文件在整体生命周期里会遇到的阶段: xxxx.class --->加载---->连接--->初始化---> 使用--->卸载。

    我们将会在本章讨论一下xxxx.class--->加载--->连接---->初始化的过程。

    讨论的方式采用自问自答模式:

    1 首先类什么时候会被加载

    答:这一点JVM并没有强制约束,由不同的JVM供应商自行实现。但是是JVM规定了类初始化的有且只有的5种情况。

         a 对静态属性和方法进行读写、NEW一个实例

         b 通过反射Class.forName获取实例

         c 初始化子类时他的父类没有进行过初始化,则会触发父类的初始化

         d main函数入口的类

         e JDK1.7动态语言的支持MethodHandle(这个暂时不理解)

    另外这里需要提醒一下

        A 接口的与类的区别,子类的初始化不会触发接口的初始化。

        B NEW一个数组类不会触发当前数组类型的类的初始化,但会初始化JAVA虚拟机里面的一个继承object的数组的子类

          例如 ClassArrayTest[] testArray = new ClassArrayTest[10] ,这句话不会初始化CLassArrayTest类的。

        C 常量final 修饰的static属性被读取时不会触发初始化的过程

    2 加载阶段是做了什么?

    答:首先“加载”和“类加载”别混淆,加载是类加载的其中一个步骤(同样的初始化是类加载的最后一步)。,

          言归正传,JVM在类需要初始化时会先把Class文件转换成二进制模式放入JVM控制的内存里面的方法区中,这个过程叫做加载。

    3 连接的阶段是做了什么?(详情在4,5,6一并回答)

    答:连接阶段分为三个步骤:验证、准备、解析(解析的步骤不确定是否会执行,因为它的执行顺序可以由虚拟机调节)。

    4 验证

    答:这一阶段的目的是为了确保Class的正确性,从以下几个方面展开

         1 文件格式

                       版本号是否符合当前JVM范畴

                       文件是否完整

        2 元数据 

                      语法是否符合规范

        3 字节码 

                      堆栈的操作是否合理

         4 符号引用 

                      类里面属性和方法的访问权限是否正确

    5 准备

    答:这一阶段是为类的静态属性附上初始值,比如 整形是0,浮点是0.0f/d 引用类型是null。

          提醒一点:final常量在这里是直接进行赋值的,所以他不会触发初始化。

    6 解析

    答:解析阶段是把符号引用转为直接引用什么是符号引用呢?比如一个类中有个属性是一个其他类的实例 A a = new A(); 其中a 就是符号引用。

         为什么需要这一步骤呢?按照我的理解是直接引用的意义明确而且无歧义,并且确保了被引用的对象一定已经创建(不创建哪来引用地址呢?)。

         开始详解一下解析的过程。解析的过程分为2大块,类/接口解析与字段解析

         1 类/接口的解析(创建其他类并且获取指针的过程)

                       step1  确定被引用的是否为数组,如果是数组则由虚拟机加载表示当前数组维度的数组类

                       step2  如果不是数组,则把这个需要加载的类传递给当前类的加载器进行加载

                       step3 如果1,2都通过时,则检查被引用类的访问权限,失败会抛出illegalAccessError

         2 字段解析(在第一步的基础上把指针指向方法或者属性的过程)

                       step1 在被引用的类里面寻找需要的属性和方法,找到返回。

                       step2 第一步未找到时,从下至上遍历他的父类和接口直到找到object类结束

                       step3 step1和step2 都未能找到时则抛出NoSuchFieldError

    7 初始化阶段做了什么?

    答:类加载的最后一步了。为所有静态变量赋值和执行静态块语句。

    另外JVM是会确保类的初始化被正确的加锁,以避免并发的风险。(利用这个机制,我们再进行单例模式设计时会使用到。)

  • 相关阅读:
    149. Max Points on a Line(js)
    148. Sort List(js)
    147. Insertion Sort List(js)
    146. LRU Cache(js)
    145. Binary Tree Postorder Traversal(js)
    144. Binary Tree Preorder Traversal(js)
    143. Reorder List(js)
    142. Linked List Cycle II(js)
    141. Linked List Cycle(js)
    140. Word Break II(js)
  • 原文地址:https://www.cnblogs.com/sunfan1988/p/3961920.html
Copyright © 2011-2022 走看看