当前位置 : 主页 > 编程语言 > java >

JVM类加载的几个过程

来源:互联网 收集:自由互联 发布时间:2022-07-05
这是类加载的过程,加载的类是放到了 JVM 的元数据空间,也就是永久代。 • 加载:根据查找路径找到相应的 class 文件然后导入; • 检查:检查加载的 class 文件的正确性; • 准备:

这是类加载的过程,加载的类是放到了 JVM 的元数据空间,也就是永久代。

• 加载:根据查找路径找到相应的 class 文件然后导入;

• 检查:检查加载的 class 文件的正确性;

• 准备:给类中的静态变量分配内存空间;

• 解析:虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用就理解为一个标示,而在直接引用直接指向内存中的地址;

• 初始化:对静态变量和静态代码块执行初始化工作。

JVM类加载的几个过程_静态变量

概述

通过全限定名来加载生成 class 对象到内存中,然后进行验证这个 class 文件,包括文件格式校验、元数据验证,字节码校验等。准备是对这个对象分配内存。解析是将符号引用转化为直接引用(指针引用),初始化就是开始执行构造器的代码

类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading)、验证(Verification)、准备 (Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using) 和卸载(Unloading)7 个阶段。其中准备、验证、解析 3 个部分统称为连接(Linking)。

加载、验证、准备、初始化和卸载这 5 个阶段的顺序是确定的,类的加载过程必须按照这种顺序按部就班地开始,而解析阶段则不一定:它在某些情况下可以在初始化阶段之后再开始,这是为了支持 Java 语言的运行时绑定(也称为动态绑定或晚期绑定)。

java 类加载需要经历下面5 个过程:

加载

查找并加载类的二进制数据(把 class 文件里面的信息加载到内存里面)

加载时类加载的第一个过程,在这个阶段,将完成一下三件事情:

  • 通过一个类的全限定名获取该类的二进制流。
  • 将该二进制流中的静态存储结构转化为方法去运行时数据结构。
  • 在内存中生成该类的 Class 对象,作为该类的数据访问入口。
  • 验证

    把内存中类的二进制数据合并到虚拟机的运行时环境中

    验证的目的是为了确保 Class 文件的字节流中的信息不会危害到虚拟机. 在该阶段主要完成,

    以下四钟验证:

  • 文件格式验证:验证字节流是否符合 Class 文件的规范,如主次版本号是否在当前虚拟机范围内,常量池中的常量是否有不被支持的类型.
  • 元数据验证: 对字节码描述的信息进行语义分析,如这个类是否有父类,是否集成了不被继承的类等。
  • 字节码验证:是整个验证过程中最复杂的一个阶段,通过验证数据流和控制流的分析,确定程序语义是否正确,主要针对方法体的验证。如:方法中的类型转换是否正确,跳转指令是否正确等。
  • 符号引用验证:这个动作在后面的解析过程中发生,主要是为了确保解析动作能正确执行。
  • 准备

    准备阶段是为类的静态变量分配内存并将其初始化为默认值,这些内存都将在方法区中进行分配。准备阶段不分配类中的实例变量的内存,实例变量将会在对象实例化时随着对象一起分配在 Java 堆中。

    public static int value=123;// 在准备阶段 value 初始值为 0 。在初始化阶段才会变为 123 。

    解析

    该阶段主要完成符号引用到直接引用的转换动作。解析动作并不一定在初始化动作完成之前,也有可能在初始化之后。

    把类中的符号引用转化为直接引用(比如说方法的符号引用,是有方法名和相关描述符组成,在解析阶段,JVM 把符号引用替换成一个指针,这个指针就是直接引用,它指向该类的该方法在方法区中的内存位置)

    初始化

    为类的静态变量赋予正确的初始值。当静态变量的等号右边的值是一个常量表达式时,不会调用 static 代码块进行初始化。只有等号右边的值是一个运行时运算出来的值,才会调用 static 初始化。

    初始化时类加载的最后一步,前面的类加载过程,除了在加载阶段用户应用程序可以通过自定义类加载器参与之外,其余动作完全由虚拟机主导和控制。到了初始化阶段,才真正开始执行类中定义的 Java 程序代码。


    上一篇:JVM类加载器和双亲委派模型
    下一篇:没有了
    网友评论