[JVM]虚拟机类加载机制

运行前的准备工作

  在javac编译成.class文件中的字节流后,在运行时jvm要将.class文件加载到JVM中,并且进行相应的处理便于之后的运行。

整个加载到运行中的步骤如下

1.加载 2.连接(验证,准备,解析)3.初始化 4.使用 5.卸载

可以看到初始化之前需要完成loading和linking的过程,初始化的时机在虚拟机规范中有明确的规定

在虚拟机启动时会先对main所在的主类进行加载/连接/初始化

其他类的初始化发生在:

1.使用new指令创造一个类的对象时

2.使用getstatic,putstatic或invokestatic对静态字段进行读写操作,以及调用一个类的静态方法时

3.初始化该类时,其父类还没有初始化,先初始化该类的父类

4.MethodHandle?

以上几种情况称为对一个类进行主动引用,以上操作会引发JVM对类的初始化,所以初始化之前的准备工作(加载,连接)应该在之前完成

加载

类加载过程

非数组类:

1.jvm通过类的全限定名获取此类的二进制流(classloader完成的工作,)

2.将字节流转化为方法区该类的数据结构

3.生成class对象作为方法区该类数据的访问入口

数组类的加载:

数组类本身不是由类加载器加载,而是由虚拟机直接加载的

数组类的标识规则如下

reference的数组:数组将在加载该组件类型的类加载器的类名称空间被标识

primitive type的数组:与引导类加载器关联

ClassLoader与Class

每个类必须与类加载器一起确定唯一性,两者共同标识一个类

ClassLoader决定了用户获取需要的类的方式

编译后的.class文件,经过不同的ClassLoader加载到JVM,在方法区中产生两个不同的类

Class类中的equals(),isInstance()都对ClassLoader进行比较

验证

验证在加载后进行,JVM验证加载到方法区的Class字节流是否符合当前虚拟机的要求

准备

static与static final变量的赋值时机

  static final变量在准备阶段就已经完成赋值,该字段在编译时会生成ConstantValue的属性表,准备阶段jvm通过读取方法区中该字段表的属性表给静态常量赋值

  static变量作为类变量,在类初始化时通过函数赋值,实例变量通过进行赋值

 

 

 

你可能感兴趣的:(JVM)