虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。

类从被加载到虚拟机内存开始,到卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段。

类的生命周期

1.加载

"加载"是"类加载"这个过程的一个阶段,是 “类加载”过程中最先开始进行的操作,加载阶段,虚拟机需要完成三件事:

  1. 根据类的全限定名获取定义此类的二进制字节流;
  2. 将这个字节流代表的静态存储结构转换为方法区的运行时数据结构;
  3. 在方法区中为这个类生成一个java.lang.Class对象,作为方法区这个类的访问入口。

2.验证

验证是连接的第一步,这一阶段的目的是为了确保Class文件的字节流包含的信息符合当前虚拟机的要求,并且不会危害到虚拟机自身的安全。虚拟机如果不检查输入的字节流,对其完全信任的话,很可能会因为载入了有害字节流而导致系统崩溃。

(1)文件格式验证

检查字节流是否符合Class文件格式的规范,并且能被当前版本的虚拟机处理:

  • 是否以魔数0XCAFEBABE开头。
  • 主、次版本号是否存在当前虚拟机处理范围内。
  • 常量池的常量是否有不被支持的常量类型。
  • ... ...

(2)元数据验证

对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言规范的要求:

  • 这个类是否有父类。
  • 这个类的父类是否继承了不允许继承的类。
  • 如果这个类不是抽象类,是否实现了其父类或接口之中要求实现的所有方法。
  • ... ...

(3)字节码验证

(4)符号引用验证

3.准备

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区中进行分配。

4.解析

解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。

5.初始化

前面的类加载过程中,除了在加载阶段用户应用程序可以通过自定义类加载器参与之外,其余动作完全由虚拟机主导和控制。到了初始化阶段,才真正开始执行类中定义的Java程序代码。

虚拟机规范严格规定了有且只有5种情况必须立即对类进行“初始化”:

(1)遇到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。生成这4条指令的最常见的Java代码场景是:使用new关键字实例化对象的时候、读取或设置一个类的静态字段的时候、调用一个类的静态方法的时候。

(2)使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。

(3)当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类初始化。

(4)当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的类),虚拟机会先初始化这个主类。

(5)当使用JDK1.7的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发初始化。

6.类加载器双亲委派模型

从Java虚拟机的角度来说,只存在两种不同的类加载器:一种是启动类加载器(Bootstrap ClassLoader),这个类加载器使用C++语言实现(HotSpot虚拟机中),是虚拟机自身的一部分;另一种就是所有其他的类加载器,这些类加载器都有Java语言实现,独立于虚拟机外部,并且全部继承自java.lang.ClassLoader。

从开发者的角度,类加载器可以细分为:

启动类加载器:负责将 Java_Home/lib下面的类库加载到内存中(比如rt.jar)。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作。

扩展类加载器:由sun.misc.Launcher$ExtClassLoader实现。它负责将Java_Home /lib/ext或者由系统变量 java.ext.dir指定位置中的类库加载到内存中。开发者可以直接使用标准扩展类加载器。

应用程序类加载器:由 sun.misc.Launcher$AppClassLoader实现的。它负责将系统类路径(CLASSPATH)中指定的类库加载到内存中。开发者可以直接使用这个类加载器。

除此之外,还有自定义的类加载器,它们之间的层次关系被称为类加载器的双亲委派模型。该模型要求除了顶层的启动类加载器外,其余的类加载器都应该有自己的父类加载器,而这种父子关系一般通过组合(Composition)关系来实现,而不是通过继承(Inheritance)。

类加载器双亲委派模型

双亲委派模型的工作原理是,如果一个类加载器收到了类加载请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去执行,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父类加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去加载。

优势:(1)采用双亲委派模式的是好处是Java类随着它的类加载器一起具备了一种带有优先级的层次关系,通过这种层级关可以避免类的重复加载,当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次。(2)实现简单,逻辑清晰易懂。

fegin需要实现类_深入理解JVM(六)--虚拟机类加载机制相关推荐

  1. 深入理解JVM(5)——虚拟机类加载机制

    在Class文件中描述的各种信息,最终都需要加载到虚拟机中之后才能运行和使用.而虚拟机中,而虚拟机如何加载这些Class文件?Class文件中的信息进入到虚拟机中会发生什么变化?本文将逐步解答这些问题 ...

  2. 深入理解JVM之虚拟机类加载机制

    1.概述 Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程被称作虚拟机的类加载机制.与那些在编译时需要进 ...

  3. jvm垃圾回收机制_深入理解JVM的垃圾回收机制

    ​如何判断对象已"死" Java堆中存放着几乎所有的对象实例,垃圾回收器在堆进行垃圾回收前,首先要判断这些对象那些还存活,那些已经"死去".判断对象是否已&qu ...

  4. jvm(7)-虚拟机类加载机制

    [0]README 0.1)本文转自"深入理解jvm",旨在学习  虚拟机类加载机制 的基础知识: [1]概述 1)类加载机制:虚拟机把描述类的数据从Class 文件加载到内存,并 ...

  5. 【深入理解JVM】ClassLoader类加载机制

    Java程序并不是一个原生的可执行文件,而是由许多独立的类文件组成,每一个文件对应一个Java类.此外,这些类文件并非立即全部装入内存的,而是根据程序需要装入内存.ClassLoader专门负责类文件 ...

  6. 深入理解JVM虚拟机(六):虚拟机类加载机制

    1. 概述 虚拟机把描述类的数据从Class文件加载到内存中,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类记载机制. 与那些在编译时需要进行连接工作 ...

  7. java虚拟机类加载机制_《深入理解java虚拟机》学习笔记一/类加载机制

    为何要读这本书? 近期看了左萧龙大哥的单例设计模式,后文讲解到了JVM对类实例化相关知识,感觉看着很无力,不懂,于是乎买本书研究下. 如何读? 个人水平一般,理解程度有限,书中说到每章关联不是很大,所 ...

  8. 【深入理解JVM】:类加载器与双亲委派模型

    转载自  [深入理解JVM]:类加载器与双亲委派模型 类加载器 加载类的开放性 类加载器(ClassLoader)是Java语言的一项创新,也是Java流行的一个重要原因.在类加载的第一阶段" ...

  9. 深入理解虚拟机之虚拟机类加载机制

    <深入理解Java虚拟机:JVM高级特性与最佳实践(第二版>读书笔记与常见相关面试题总结 本节常见面试题(推荐带着问题阅读,问题答案在文中都有提到): 简单说说类加载过程,里面执行了哪些操 ...

最新文章

  1. 使用GoAccess分析Nginx日志
  2. 用Flash MX 2004自制调色版和配色组件(一)
  3. [Nowcoder] 寻找子串
  4. 51NOD 1138 连续整数的和
  5. linux手工迁移php,Linux+PHP+MySql网站迁移配置
  6. 最早将于Q3季度发布,小米12至尊版将搭载骁龙8 Plus
  7. phpcms图片无法上传
  8. 理解Load Average做好压力测试
  9. Mock生成随机数据常用的类型规则
  10. Java中的内存处理机制和final、static、final static总结
  11. 【免费分享】收集整理的117套各类微信小程序模板源码分享
  12. C语言笔记 清屏(循环时不一闪一闪的) 光标移动到任意位置 带注释(详细)
  13. Win10网卡驱动突然消失
  14. Ubuntu18.04无法安装软件的问题
  15. 傅里叶分析之看不懂就掐死我吧(完整版)
  16. 阿里云服务器租赁注意点
  17. 网页报错:You don't have permission to access
  18. python涨停分析 -股票量化
  19. 【数据结构系列】单链表
  20. 基于STM32智能小车蓝牙遥控实验(有代码含上位机)

热门文章

  1. 开发工具 | git、github使用场景总结
  2. ava RMI 框架(远程方法调用)
  3. MySQL datetime类型字段的毫秒四舍五入
  4. 十大互联网公司都在寻找她!她是什么样的?
  5. [Javascript]编程风格
  6. 解决Jenkins Email Extension Plugin发送邮件失败
  7. 【Vegas原创】添加SQL Server Agent作业步骤中的运行身份
  8. 石川es6课程---3、变量let和常量const
  9. (3)数据库的建立和数据表的操作
  10. mapreduce原理