资讯专栏INFORMATION COLUMN

Java中类加载机制

missonce / 988人阅读

摘要:类加载器类加载器执行的操作就是上述加载阶段做的事,通过一个类的全限定名来获取定义这个类的二进制字节流,类加载器可以分为下列三种。应用程序类加载器,也称为系统类加载器。

类加载流程:


从上面这幅图可以看出一个类从加载到卸载有7个阶段,其中验证、准备和解析这三个步骤统称为连接。类加载的过程一定会经过加载、验证、准备、初始化和卸载这5个过程,解析和使用则不一定。还有一点要注意的是,并不是每个步骤完全执行完之后才会调用下一个步骤,它会在一个步骤执行的过程中就调用下一个步骤,只是开始的时候一定会按这个顺序。

类加载每个步骤的操作:

一、加载
加载过程会做下面三件事。

通过一个类的全限定名来获取定义这个类的二进制字节流。

将这个字节流的静态存储结构转化为方法区运行时的数据结构。

在内存中为这个类生成一个java.lang.Class对象,作为方法区这个类的访问入口。

二、验证
验证是为了确保加载进来的Class文件的字节流里的内容是符合当前虚拟机的要求,不会危害虚拟机自身的安全,比如一些非法的语句之类的,会进行下面4步验证。

文件格式验证,验证字节流是否符合Class文件格式的规范,可以被当前虚拟机处理。

元数据验证,对加载进来的类的元数据进行语义验证,保证都符合Java语言规范。

字节码验证,这一步是在确保元数据符合Java语言规范后再验证它是否有非法的,不合逻辑的地方。比如调用一个方法返回int,却声明一个double变量去接这个值。

符号引用验证,就是对常量池中的各种符号引用进行验证,看这些符号引用是否能被当前类访问到。

三、准备
这个阶段就是给类变量分配内存并且设置初始化值,注意这里只是会分配内存给类变量,实例变量只有在对象初始化的时候才会分配。
四、解析
在这个阶段是把符号引用替换为直接引用的过程。
五、初始化
初始化是是类加载过程中的最后一步,它会根据代码中的定义再去初始化类变量和其他的资源,到这一步就表示整个类已经初始化完成了。

类加载器:

类加载器执行的操作就是上述加载阶段做的事,通过一个类的全限定名来获取定义这个类的二进制字节流,类加载器可以分为下列三种。

启动类加载器,它负责加载存放在lib目录下或者是被-Xbootclasspath参数所指定的路径中的类库。

扩展类加载器,负责加载存放在libext目录或者是java.ext.dirs系统变量所指定的路径中的类库,这个加载器我们可以直接使用。

应用程序类加载器,也称为系统类加载器。负责加载用户类路径(ClassPath)上所指定的类库,这个加载器我们也可以直接使用。

双亲委派模型:

双亲委派模式的结构就是上图所示,要求除了最顶层的启动类加载器之外其他的类加载器都要有自己的父类。这里的父类不是用继承实现的,是通过组合方式来复用父类类加载器。它的工作原理是当一个类加载器收到了类加载的请求,不会先自己去加载,而是先委派给父类加载器去执行,父类加载器如果也有它的父类就继续委派上去,直到最顶层的启动类加载器为止。而当父类没办法加载的时候再一层一层往下返回,让它的子类加载器去加载。

优点:
这样的好处在于让类加载器有一种优先级的层级关系。这里要提到一点,判断两个类是否相等,除了要判断是否是同一个Class文件加载的还需要看是不是同一个类加载器加载出来的。如果不是同一个类加载器加载的,即使是同一个Class文件加载出来的类也是不相同的。举个例子,比如java.lang.Object类,当它被加载的时候一定会被委派到最顶层的启动类加载器去加载。所以无论你拿什么类加载器去加载,最后得到的Object类都是同一个类。如果没有这种委派关系的话,都是Object类,但是由不一样的类加载器加载的,各自加载出来的Object类也不相同,会造成一片混乱。

这篇文章只是大致上讲了Java中类加载的过程和类加载器的设计。中间还有很多细节没有做详细说明。如果还想要再详细了解的话可以去看一下《深入理解Java虚拟机:JVM高级特性与最佳实践 第2版 》这本书,本篇文章的内容在这本书的第七章里有详细的解释。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69151.html

相关文章

  • jvm类加载机制

    摘要:前面提到,对于数组类来说,它并没有对应的字节流,而是由虚拟机直接生成的。对于其他的类来说,虚拟机则需要借助类加载器来完成查找字节流的过程。验证阶段的目的,在于确保被加载类能够满足虚拟机的约束条件。 Java 虚拟机将字节流转化为 Java 类的过程。这个过程可分为加载、链接以及初始化 三大步骤。 加载是指查找字节流,并且据此创建类的过程。加载需要借助类加载器,在 Java 虚拟机中,类...

    lastSeries 评论0 收藏0
  • Java加载机制

    摘要:当前类加载器和所有父类加载器都无法加载该类时,抛出异常。加载两份相同的对象的情况和不属于父子类加载器关系,并且各自都加载了同一个类。类加载机制与接口当虚拟机初始化一个类时,不会初始化该类实现的接口。 类加载机制 概念 类加载器把class文件中的二进制数据读入到内存中,存放在方法区,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。 1、加载: 查...

    aaron 评论0 收藏0
  • JVM 知识点 01

    摘要:新生代又被划分为三个区域和两个幸存区。这样划分的目的是为了使能够更好地管理堆内存中的对象,包括内存的分配及回收。新生代主要存储新创建的对象和尚未进入老年代的对象。 在Java中主要有以下三种类加载器: 引导类加载器(bootstrap class loader) --用来加载java的核心库(Strin...

    不知名网友 评论0 收藏0
  • 我的面试准备过程--JVM相关

    摘要:程序计数器程序计数器是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。它的主要缺点有两个一个是效率问题,标记和清除过程的效率都不 Jvm 相关  类加载机制 本段参考 http://www.importnew.com/2374... 类加载概念 类加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个ja...

    Towers 评论0 收藏0
  • 深入理解虚拟机之虚拟机类加载机制

    摘要:最终形成可以被虚拟机最直接使用的类型的过程就是虚拟机的类加载机制。即重写一个类加载器的方法验证验证是连接阶段的第一步,这一阶段的目的是为了确保文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。 《深入理解Java虚拟机:JVM高级特性与最佳实践(第二版》读书笔记与常见相关面试题总结 本节常见面试题(推荐带着问题阅读,问题答案在文中都有提到): 简单说说类加载过...

    MadPecker 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<