JVM学习(二):类加载

jkouu 59 0

这篇文章记录的是JVM类加载放入相关知识。

类加载机制

JVM类加载机制分为加载、验证、准备、解析和初始化五个步骤。在这基础上再加上使用和卸载两个步骤,就构成了类从进入JVM内存到移出内存的全部流程。在学习类加载的步骤前,应该先要学习类加载的时机。JVM规范规定了类必须被初始化的物种情况:

1.遇到new、getstatic、pustatic、invokestatic这四个字节码指令的时候

2.使用java.lang.reflect包对类进行反射调用的时候

3.初始化子类的时,作为父类没有被初始化的时候

4.java.lang.invoke.MethodHandle实例最后的解析结果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄所对应的类没有进行过初始化的时候

加载

加载步骤由JVM的类加载器完成,主要有三个任务:

1.通过类的全扩展名加载对应的二进制字节码

2.将字节码代表的静态存储结构转为方法区的运行时数据结构

3.在堆区创建一个代表此类的java.lang.Class对象,作为访问上述数据结构的入口

我们都知道类文件是字节码的一个来源。事实上,类加载器不仅还可以通过zip、jar、txt等文件中加载字节码,而且还可以通过网络获取字节码。

还值得一提的是,类加载器其实也是一个Java类(继承自虚拟类Java.lang.ClassLoader)。这意味着我们也可以继承默认的类自定义自己的类加载器。所以加载步骤是用户可以参与的。

验证

验证步骤主要是为了防止加载的字节码对虚拟机有破坏作用。主要的验证任务有三个:

1.文件格式验证:检查加载的字节码文件是否合乎规范以及是否能被当前版本的虚拟机处理

2.元数据验证:对字节码进行语义分析,保证其符合Java语言规范

3.字节码验证:对类的方法体进行数据流和控制流分析,保证其不会对虚拟机造成危害

准备

在准备阶段,所有的类变量被正式分配内存并初始化

解析

解析阶段主要负责将常量池中关于类、接口、成员变量、方法的符号引用转换为直接引用。在这个过程中,JVM还会进行一次符号引用验证,对符号引用的进行匹配性检验

初始化

在初始化步骤,JVM才开始真正执行字节码。前面说过,在准备阶段,所有的类变量被初始化过一次。那次的初始化值是JVM要求的值,而在初始化阶段进行的初始化才是字节码要求的初始值。好比说,int a=5;在准备阶段初始化后,a实际上是0;在初始化阶段才被初始化为5。

类加载器

JVM的类加载器有一个偏序关系:

JVM学习(二):类加载

JVM的类加载使用了所谓的“双亲委托机制”。简单点说就是先让高级的类处理,它处理不了自己再处理。启动类加载器就是最高级的类,自定义加载器是最低级的类。我们从顶部开始介绍这些加载类。

启动类加载器

启动类加载器(Bottstrap ClassLoader)是用C++实现的加载类。因为不是Java类,所以并不能在Java中被访问。启动类加载器负责加载Java.lang.Object、Java.lang.String这些系统级的Java类,从逻辑关系可以推测,扩展类加载器一下的类也应该是它加载的。因为加载类文件的Java类不可能加载自己。

扩展类加载器

扩展类加载器是Java能访问到的最顶级的加载器,负责加载$JAVA_HOME/lib/ext的类。

用户类加载器

用户类加载器负责加载应用程序classpath下的.jar和.class文件。

自定义加载类

自定义加载器是继承了java.lang.ClassLoader抽象类的Java类,由用户自定义实现。

 

发表评论 取消回复
您必须 [登录] 才能发表评论!
分享