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

  • 相关阅读:
    .NET Core WEB API使用Swagger生成在线接口文档
    .NET Core WEB API中接口参数的模型绑定的理解
    .Net Core使用视图组件(ViewComponent)封装表单文本框控件
    在有主分支和个人分支情况下的TFS使用方法
    SQL Server Profiler (SQl跟踪器)的简单使用
    C# 多线程下的单例模式
    C# 单例模式
    .net core MVC接受来自自前端的GET和POST请求方法的区别
    《Windows Phone 8 Development Internals》读书笔记-1-2-2-连载
    《Windows Phone 8 Development Internals》读书笔记-1-2-1-连载
  • 原文地址:https://www.cnblogs.com/sunfan1988/p/3961920.html
Copyright © 2011-2022 走看看