7°

JVM类的加载

1、首先类的加载共分为7个步骤

加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载

加载

class B{
    public static void main(String[] args) {
        A a = new A();
    }
}

当我们的代码中使用到某个类时,JVM会将用到的类加载到内存中.

首先你的代码中包含“main()”方法的主类一定会在JVM进程启动之后被加载到内存,开始执行你的“main()”方法中的代码,接着就会将A.class加载到内存中

验证

根据Java虚拟机的规范来检测class文件是否正确,

准备

class B{
    public static void main(String[] args) {
        A a = new A();
    }
}

class A { static int a1; int a2 = 100; }

当class文件验证没有问题后,JVM开始进行准备工作,为类A分配一定的内存空间,然后初始化static变量分配默认值

解析

解析阶段是虚拟机将常量池内的符号引用替换成直接引用的过程。直接引用是直接指向目标的指针,相对偏移量或是一个能间接定位到目标的句柄。直接引用和虚拟机实现的内存有关,同一个符号引用在不同虚拟机实例上翻译出来的直接引用不尽相同

初始化

初始化阶段是类加载过程的最后一步,到了该阶段才真正开始执行类定义的Java程序代码,根据程序员通过代码定制的主观计划去初始化类变量和其他资源,是执行类构造器初始化方法的过程

执行new A();初始化这个类的实例,那么会加载这个类,然后初始化这个类,如果初始化之前父类没有没加载,那么需要先加载父类然后初始化。

使用

卸载

被GC回收

2、 类加载器的种类

2.1、Bootstrap ClassLoader

用于加载JAVA_HOME/jre/lib文件夹中的jar文件,支撑你的java程序运行的核心类库

2.2、Extension ClassLoader

用于加载JAVA_HOME/jre/lib/ext文件夹中的jar文件,支撑你的java程序运行的扩展库

2.3、Application ClassLoader

用于加载classpath下的jar文件,大致就理解为去加载你写好的Java代码吧,这个类加载器就负责加载你写好的那些类到内存里。

2.4、自定义加载器

根据自己的需求自定义实现加载器

3、类加载的双亲委派机制

JVM的类加载器是有亲子层级结构的,就是说启动类加载器是最上层的,扩展类加载器在第二层,第三层是应用程序类加载器,最后一层是自定义类加载器。双亲委派机制正式基于这种结构实现的

假设你的应用程序类加载器需要加载一个类,他首先会委派给自己的父类加载器去加载,最终委派传导到顶层的类加载器去加载

Application ClassLoader --委派不加载-->>> Extension ClassLoader --委派不加载-->>> Bootstrap ClassLoader

然后从顶层依次向下查找要加载的类

Application ClassLoader --查找加载-->>> Extension ClassLoader --查找加载-->>> Bootstrap ClassLoader

如果找到就直接返回,找不到则抛出ClassNotFoundException异常。

3.1、双亲委派模式的好处

因为这样可以避免重复加载,当父亲已经加载了该类的时候,就没有必要 ClassLoader再加载一次。考虑到安全因素,我们试想一下,如果不使用这种委托模式,那我们就可以随时使用自定义的String来动态替代java核心api中定义的类型,这样会存在非常大的安全隐患,而双亲委托的方式,就可以避免这种情况,因为String已经在启动时就被引导类加载器(Bootstrcp ClassLoader)加载,所以用户自定义的ClassLoader永远也无法加载一个自己写的String,除非你改变JDK中ClassLoader搜索类的默认算法。

类加载器虽然只用于实现类的加载动作,但它在Java程序中起到的作用却远远不限于类加载阶段。对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性,每一个类加载器,都拥有一个独立的类名称空间。这句话可以表达更通俗一些:比较两个类是否”相等”,只有再这两个类是有同一个类加载器加载的前提下才有意义,否则,即使这两个类来源于同一个Class 文件,被同一个虚拟机加载,只要加载它们的类加载器不同,那这两个类就必定不相等。

本文由【k】发布于开源中国,原文链接:https://my.oschina.net/kdy1994/blog/3072973

全部评论: 0

    我有话说: