【理解HotSpot虚拟机】类的加载机制

转载请注明出处:http://blog.csdn.net/linxdcn/article/details/73555233


1 概述

虚拟机规范规定,一个定义的类(class文件)被虚拟机加载到内存中,经过了3个过程:

  • 加载(Loading)
  • 连接(Linking)
    • 验证(Verification)
    • 准备(Preparation)
    • 解析(Resolution)
  • 初始化(Initialization)

之后这个类就能被使用了:

  • 实例化(Instantiation)

下面以下面的类来说明类的加载机制:

public class ClassDemo {

    public static int a = 1;

    static {
        System.out.println("initialized");
    }

    public int b = 2;

    public ClassDemo() {
        System.out.println("constructed");
    }
}

2 加载

  1. 根据一个类的全限定名,找到class文件,形成class文件二进制数据流
  2. 初步校验,如class文件的魔数、主次版本号、访问标识等
  3. 解析该二进制数据流为instanceKlass对象,保存在方法区内
  4. 创建一个该类型的java.lang.Class实例,保存在堆中




3 连接

3.1 验证

验证是连接的第一步,大体上验证可以分为4个阶段:

  1. 文件格式验证(已经在上一步骤:加载中实现)
  2. 元数据验证
  3. 字节码验证
  4. 符号引用验证

详细的具体内容可以参考《虚拟机规范》和《深入理解Java虚拟机》。

这一步骤方法区和堆区中没有发生变化。

3.2 准备

准备阶段是为类变量(静态变量)分配内存,并将静态变量赋值默认初始值。而不是为实例变量。

默认初始值如下:

数据类型默认初始值数据类型默认初始值
int0booleanfalse
long0Lfloat0.0f
short(short)0double0.0
char‘\u0000’referencenull
byte(byte)0



3.3 解析

解析是虚拟机将常量池内的符号引用替换成直接引用,直接引用可以是直接指向目标的指针、相对偏移量、一个能定位到目标的句柄。




4 初始化

对类变量赋予指定的初始值,初始化阶段是执行类构造器<clinit>()方法的过程,<clinit>()方法由编译器按顺序收集

  • 静态变量的赋值动作
  • 静态语句块中的语句




5 实例化

创建类的对象实例,实例化是在类的初始化之后,是在堆上创建一个类的对象。

类的初始化会从祖先类到子类、按出现顺序,对类变量的初始化语句、静态初始化语句块依次进行初始化。而对类实例的初始化也类似,会从祖先类到子类、按出现顺序,对类成员的初始化语句、实例初始化块、构造方法依次进行初始化。




转载请注明出处:http://blog.csdn.net/linxdcn/article/details/73555233

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页