关于类加载机制 电玩女神 2022-05-23 01:25 89阅读 0赞 Java在刚刚诞生时提出过一个非常著名的宣传口号:”一次编写,到处运行”,java可以运行在不同的平台上,而Java语言之外的语言,如Clojure、Groovy、JRuby、Jython、Scala等也可以在Java虚拟机上运行。这种实现语言无关性的基础得益于虚拟机和字节码存储格式。 ![这里写图片描述][70] 在Java代码被编译成Class文件(.class),在Class文件中描述的各种信息,最终都需要加载到虚拟机中之后才能运行和使用。 #### 什么是类加载机制 #### 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型。 在Java语言里,类型的加载、连接和初始化过程都是在程序运行期间完成的。Java里天生可以动态扩展的语言特性就是依赖运行期动态加载和动态连接这个特点实现的。例如编写一个面向接口的应用程序,可以等到运行时再指定其实际的实现类; #### 类加载的时机 #### 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用、卸载,其中验证、准备、解析3个部分统称为连接。 ![这里写图片描述][70 1] 其中加载、验证、准备、初始化和卸载这5个阶段的顺序是确定的,类的加载过程必须按照这种顺序按部就班的开始。而解析阶段则不一定:在某些情况下可以在初始化阶段之后再开始。 什么情况下需要开始类加载过程的第一阶段:加载,Java虚拟机规范中并没有强制约束。但是对于初始化阶段有严格规定,有且只有5种情况必须立即对类进行“初始化”; 1、遇到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。例如:使用new关键字实例化对象的时候、读取或设置一个类的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外)的时候,以及调用一个类的静态方法的时候。 2、使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化 3、当初始化一个类的时候,其父类还没有进行初始化,则需要先触发其父类的初始化 4、当虚拟机启动时,用户需要指定一个要执行的主流(包含main()方法的那个类),虚拟机会先初始化这个主类 5、当使用JDK1.7的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF\_getStatic、REF\_putStatic、REF\_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化。 #### 类加载的过程 #### **加载** 在加载阶段,虚拟机需要完成3件事情: 1. 通过一个类的全限定名来获取定义此类的二进制字节流 2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构 3. 在内存中生产一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口 **验证** 验证是连接阶段的第一步,这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。大致分为4个阶段的验证动作:文件格式验证(例如是否以魔数0xCAFEBABE开头。主、次版本号是否在当前虚拟机处理范围之内)、元数据验证(例如这类是否有父类。这个类是否继承了不被允许继承的类)、字节码验证(例如保证跳转指令不会跳转到方法体以外的字节码指令上)、符号引用验证(例如符号引用中通过字符串描述的全限定名是否能找到对应的类) **准备** 准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区中进行分配。这时候进行的内存分配仅包含类变量(被static修饰的变量),而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在Java堆中。(注意这里的初始值并非代码中的值,譬如int类型则初始值为0) **解析** 解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。 符号引用:符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可。符号引用与虚拟机实现的内存布局无关,引用的目标并不一定已经加载到内存中。 直接引用:直接引用可以是直接指向目标的指针、相对偏移量或是一个能间接定位到目标的句柄。直接引用是和虚拟机实现的内存布局相关的,同一个符号引用在不同的虚拟机实例上翻译出来的直接引用一般不会相同。如果有了直接引用,则引用的目标必定已经在内存中存在。 **初始化** 类初始化是类加载过程的最后一步,除了在加载阶段用户应用程序可以通过自定义加载器参与之外,其余动作完全由虚拟机主导和控制。到了初始化阶段,才真正开始执行类中定义的Java程序代码。 本文来自《深入理解java虚拟机》 [70]: /images/20220523/99d3928aeb3b41ac819e2af566bd6b86.png [70 1]: /images/20220523/7a1ecf6d4b494a8ba88c7bd67bffb3d4.png
相关 类加载机制 1.类加载流程 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG 骑猪看日落/ 2022年12月26日 10:26/ 0 赞/ 206 阅读
相关 类加载机制 一、类加载的几个阶段 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9i 末蓝、/ 2022年12月25日 15:54/ 0 赞/ 233 阅读
相关 类加载机制 点击上方“晏霖”,选择“置顶或者星标” 曾经有人关注了我 后来他有了女朋友 1.6类加载机制 1.6.1概述 学习本章前我们要对类文件结构有一个简单的认识,而学 迷南。/ 2022年12月22日 11:16/ 0 赞/ 221 阅读
相关 类加载机制 我们都知道java中比较常提到的一个概念就是类。但是在java机制中,类是怎么运行的呢?下面来看看L: 类被加载到虚拟机到使用,最后被卸载,经历了一下几个步骤: ╰+哭是因爲堅強的太久メ/ 2022年07月13日 09:10/ 0 赞/ 290 阅读
相关 类加载机制 类加载器层次是怎么样的 1. JVM预定义的三种类型类加载器: 启动(Bootstrap)类加载器:是用本地代码实现的类装入器,它负责将 `<J - 日理万妓/ 2022年07月12日 07:15/ 0 赞/ 312 阅读
相关 类加载机制 类加载器层次是怎么样的 1. JVM预定义的三种类型类加载器: 启动(Bootstrap)类加载器:是用本地代码实现的类装入器,它负责将 `<J Bertha 。/ 2022年07月12日 07:15/ 0 赞/ 256 阅读
相关 类加载机制 任何一个类在使用前都要经历过完整的加载,连接和初始化三个类加载步骤。经历过这三个步骤之后类型就能随时随地被使用了。从一个类型被加载进JVM算起,直至最终被卸载出内存为止,它的整 左手的ㄟ右手/ 2022年06月10日 06:47/ 0 赞/ 351 阅读
相关 类加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个`java.lang.Class`对 骑猪看日落/ 2022年05月27日 05:08/ 0 赞/ 344 阅读
相关 关于类加载机制 Java在刚刚诞生时提出过一个非常著名的宣传口号:”一次编写,到处运行”,java可以运行在不同的平台上,而Java语言之外的语言,如Clojure、Groovy、JRuby、 电玩女神/ 2022年05月23日 01:25/ 0 赞/ 90 阅读
相关 类加载机制 java类加载的全过程包含5个步骤: 加载,验证,准备,解析,初始化 而验证,准备,解析又可以合并为一个阶段:连接 怼烎@/ 2021年10月01日 08:26/ 0 赞/ 468 阅读
还没有评论,来说两句吧...