• 类加载过程


    类加载过程本质上就是类加载器根据类的全限定名称去找到对应的class字节码文件内容,然后将字节码文件的内容加载到虚拟机方法区中的过程。
    所以我们大体上可以把类加载的过程分为三部分:
    1、加载,就是获取到class文件的内容
    2、链接,就是把相应的文件内容添加到虚拟机中,转变为虚拟机中的class对象,使虚拟机可以使用该类
    3、初始化,初始化类对象的中的数据

    也就是下面这个样子

    而链接其实是一个较为复杂的过程,所以我们把链接再拆分成
    验证、准备、解析三个更细粒度的步骤,所以总体的步骤如下图:

    而每个步骤更为详细的解释:
    1、加载-根据全限定名称去寻找这个class的字节码文件内容,然后根据字节码中的内容翻译成jvm所熟知的class数据结构并保存到内存中。
    注意这里的寻找字节码文件并不一定局限在传统的从磁盘中查找,而是非常灵活的,可以来自于db,来自于内存,来自于网络,甚至动态生成。
    这里也为class文件的安全存储提供了保证。
    2、验证-为了防止字节码文件存在恶意的信息,或者有伤害虚拟机的行为,因此需要对字节码文件的内容进行一个全面的校验。包括字节码的格式。语义、操作验证等。
    3、准备-为类的静态变量分配内存并赋予对应的默认值。如int 赋予0,对象赋予null,boolean赋予false等。
    4、解析-将常量池中的符号引用转化为直接引用。也就是说将各种对象/方法的符号名称直接替换为方法区中的指针或者地址偏移量,以便直接调用该对象/方法。
    5、初始化-会将所有的静态变量的值进行一遍初始赋值的操作。同时执行对应的静态初始化模块。

    我们为了方便常常把 验证、准备、解析是三个步骤统称为链接。而链接就是类加载过程中的核心步骤:将字节码文件的内容转化为jvm的运行时环境中可以直接用的过程。
    这个过程通常是由虚拟机来完成,我们无法过多干预。但是对于如何进行加载,也就是步骤1中的how,我们可以通过对类加载器进行重载来满足很多我们需要,这也是类加载过程中,我们能最多干预的地方。(这一部分由于内容比较大而复杂我会在后边的文章中记录)

    6、使用(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )
    7、卸载-对jvm中已经存在的class对象进行卸载。
    关于类class对象的卸载条件:
    1、该class的任何实例对象都已经被回收了。
    2、加载该class文件的classloader也已经被回收了
    3、该class文件也不存在任何地方持有他的引用。
    也就是说,从目前的角度来看,jvm基本不会再使用到该class文件。此时就可以卸载掉该class对象了

    这里要注意:
    1、类的加载前会先加载父类,只有当直接父类加载完毕后,才会挤在当前类。而直接父类的加载又要依托于直接父类的直接父类。依次类推,直至所有类加载完毕。
    2、类的加载过程中各步骤的开始是依照前文中的描述。但是为保证更高的效率,各步骤在执行阶段则可能会互相交错执行,如一边加载一边链接。同时解析阶段为了支持jvm的动态绑定(运行时绑定)原因,解析可能会在初始化步骤开始后才开始。

    3、类初始化的顺序
    会先依次执行静态变量的初始化,接着执行静态块的初始化。(如果是构造实例的话,则会接着初始化变量,初始化块,构造器)

    如果你觉得写的不错,欢迎转载和点赞。 转载时请保留作者署名jilodream/王若伊_恩赐解脱(博客链接:http://www.cnblogs.com/jilodream/

  • 相关阅读:
    Monolith and Microservice
    Lombok介绍、使用方法和总结
    Druid对应mysql-connector版本
    maven导入springboot项目
    区块链是什么?超级详细,看了无师自通!
    08.区块链的应用有什么?区块链将带来什么变革?
    06.工作量证明共识机制
    07 挖矿是什么意思?矿工都做了什么?
    05.比特币区块链的数据结构
    04.UTXO:未使用的交易输出,比特币核心概念之一
  • 原文地址:https://www.cnblogs.com/jilodream/p/15135594.html
Copyright © 2020-2023  润新知