JVM加载class文件的具体过程

JVM加载class文件的具体过程

一个class文件被加载到内存中主要有三个步骤:装载、链接、初始化。其中链接又细分为三小步:验证、准备、解析,下面一次对每一步进行大致的介绍:

一,装载:

什么是装载?装载的意思是指Java虚拟机查找.class文件并生成字节流,然后根据字节流创建java.lang.Class对象的过程。这个过程里面有可以简单的分为三小步:

  1. 查找到.class文件,并生成二进制字节流。

  2. 把字节流形式的.class文件的各个部分解析成JVM的特定数据结构,并存储在方法区。

  3. 在内存中创建java.lang.Class对象:接下来程序运行过程中所有对该类的访问都是通过这个java.lang.Class对象提供的接口来访问。

    装载的分类:

隐式装载:在程序运行过程中,碰到new等方式生成对象时,系统会隐式调用ClassLoader去装载对应的.class到内存中去

显示装载:在编写源代码时,主动调用Class.forName()等方法去主动装载.class文件到内存。

二,链接:

链接分为验证、准备和解析。

​ **验证:**是链接的第一步,主要是为了检验该.class文件的字节流中包含的信息是否符合虚拟机的要求,并且不会危及虚拟机本身的安全,主要包含以下几个方面的检验:

  1. 文件格式检验:检验字符流是否符合class文件格式规范。

  2. 元数据检验:对字节码描述信息进行语义分析,保证描述内容符合Java语言规范要求。

  3. 字节码检验:通过数据流和控制流分析,确定程序语义是否合法,符合逻辑。

  4. 符号引用检验:对类自身以外(常量池中的各种符号引用)的信息进行匹配性校验。

    准备:

为类中静态变量分配内存,并为其设置“0”值。

例如:

public static int value=100;

在准备阶段,JVM会为value分配内存,并将其值设置为0,只有当初始化时候,value才会设置其真正的值100.

在该阶段内存分配仅仅包括类变量,不包括实例变量(实例变量将在随着对象的实例化而一起分配在堆中)

而静态常量在准备阶段分配内存值是其真正的值,如:

public static final int value=100;

在准备阶段分配的值为100。

解析:

解析是链接的最后一步,这一阶段是将常量池中的符号引用转换为直接引用,也就是具体的内存地址。包括常量池中的 类、接口名、字段名、方法名等转换为具体的内存地址。

三,初始化:

这是class加载的最后一步,这一阶段是执行类构造器方法的过程,并真正初始化类变量。比如:

public static int value=100;

在准备阶段value被分配内存并设置成0,到了这一步初始化阶段设置成100。

初始化时机:

  1. 虚拟机启动时,初始化包含main方法的主类;

  2. 遇到new指令创建对象时;

  3. 访问静态方法或者静态字段的指令时;

  4. 子类的初始化过程中 如果发现父类还没有初始化时,则先初始化父类;

  5. 使用反射API进行调用时;

  6. 第一次调用java.lang.invoke.MethodHandle实例时,需要初始化MethodHandle指向方法所在类;

    初始化变量:

在初始化阶段,只会初始化与类相关的静态赋值语句和静态语句,也就是static关键字的信息,而没有static修饰的语句块在实例化对象的时候才会执行。

初始化顺序:

静态变量/静态代码块->普通代码块->构造函数

  1. 父类静态变量和静态代码块;
  2. 子类静态变量和静态代码块;
  3. 父类普通成员变量和普通代码块;
  4. 父类的构造函数;
  5. 子类普通成员变量和普通代码块;
  6. 子类的构造函数;
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值