首页 > 其他分享 >类加载机制

类加载机制

时间:2023-04-25 19:46:52浏览次数:48  
标签:Java 字节 验证 虚拟机 阶段 机制 加载

什么是类加载机制

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

类加载的时机

一个类型从被加载到虚拟机内存中开始,到卸载出内存为止,他的整个生命周期将会经历以下7个阶段:

  • 加载(Loading)
  • 验证(Verification)
  • 准备(Preparation)
  • 解析(Resolution)
  • 初始化(Initialization)
  • 使用(Using)
  • 卸载(Unloading)
    验证、准备、解析 3 个阶段统称为连接。
    image
    加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的,类型的加载过程必须按照这种顺序按部就班地开始,而解析阶段则不一定:它在某些情况下可以在初始化之后再开始,这是为了支持Java语言的运行时绑定特性(也称为动态绑定或晚期绑定)。

类加载的过程

加载

在加载阶段,Java虚拟机需要完成以下三件事:

  1. 通过一个类的全限定名来获取这个类的二进制字节流
  2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
  3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口

对于 Class 文件,虚拟机没有指明要从哪里获取、怎样获取。除了直接从编译好的 .class 文件中读取,还有以下几种方式:

  • 从ZIP压缩包中获取(JAR、EAR、WAR)
  • 从网络中获取(Web Applet)
  • 运行时计算生成(动态代理技术)
  • 由其它文件生成(JSP)
  • 从数据库读取
  • ....

验证

验证是连接阶段的第一步,这一阶段的目的是确保Class文件的字节流中包含的信息符合《Java虚拟机规范》的全部约束要求,保证这些信息被当作代码运行后不会危害虚拟机自身的安全。
Java语言本身是相对安全的,使用纯粹的Java代码无法做到像访问数组边界以外的数据、将一个对象转型成它未实现的类型、跳转到不存在的代码行之类的事情。但由于Class文件并不一定由Java源码编译而来,上诉Java代码无法做到的事在字节码层面可以实现。Java虚拟机如果不检查输入的字节流,对其完全信任的话,很可能会因为载入了错误或有恶意企图的字节码导致整个系统受到攻击甚至崩溃。
验证阶段大致上会完成下面四个阶段的检验动作:文件格式验证、元数据验证、字节码验证和符号引用验证。

1.文件格式验证

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

  • 是否以魔数 0XCAFEBABE 开头。
  • 主次版本号是否在当前虚拟机处理范围内。
  • 常量池是否有不被支持的常量类型。
  • 指向常量的索引值是否指向了不存在的常量。
  • CONSTANT_Utf8_info 型的常量是否有不符合 UTF8 编码的数据。
  • ......

文件格式验证这一阶段是基于该类的二进制字节流进行的,主要目的是保证输入的字节流能正确地解析并存储于方法区之内,格式上符合描述一个 Java 类型信息的要求。除了这一阶段之外,其余三个验证阶段都是基于方法区的存储结构上进行的,不会再直接读取、操作字节流了。

2.元数据验证

对字节码描述的信息进行语义分析,以保证其描述信息符合《Java语言规范》,这个阶段可能包括的验证点如下:

  • 这个类是否有父类
  • 这个类的父类是否继承了不被允许继承的类(被final修饰的类)
  • 如果这个类不是抽象类,是否实现了其父类或接口中要求实现的所有方法
  • ...
3.字节码验证

主要目的是通过数据流分析和控制流分析,确定程序语义是合法的、符合逻辑的。这个阶段就要对类的方法体进行校验分析,保证被校验类的方法在运行是不会做出危害虚拟机安全的行为,例如:

  • 保证任意时刻操作数栈的数据类型与指令代码序列都能配合工作,例如不会出现类似于“在操作栈放置了一个int类型的数据,使用时却按long类型来加载本地变量表中”这样的情况
  • 保证任何跳转指令都不会跳转到方法体以外的字节码指令上
  • 保证方法体中的类型转换始终是有效的,例如可以把一个子类对象赋值给父类数据类型,但是把父类对象赋值给子类数据类型,甚至把对象赋值给它毫不相干的数据类型这是危险和不合法的
  • ...
4.符号引用验证

符号引用验证发生在类加载过程中的解析阶段,具体点说是 JVM 将符号引用转化为直接引用的时候。
需要校验下列内容:

  • 符号引用中通过字符串描述的全限定名是否能找到对应的类
  • 在指定类中是否存在符合方法的字段描述符及简单名称所描述的方法和字段
  • 符号引用中的类、字段、方法的可访问性是否可被当前类访问
  • ...
    符号引用验证的主要目的是确保解析阶段能正常执行,如果无法通过符号引用验证,JVM 会抛出异常,比如:
  • java.lang.IllegalAccessError:当类试图访问或修改它没有权限访问的字段,或调用它没有权限访问的方法时,抛出该异常。
  • java.lang.NoSuchFieldError:当类试图访问或修改一个指定的对象字段,而该对象不再包含该字段时,抛出该异常。
  • java.lang.NoSuchMethodError:当类试图访问一个指定的方法,而该方法不存在时,抛出该异常。

准备

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些内存都将在方法区中分配。对于该阶段有以下几点需要注意:

  1. 这时候进行内存分配的仅包括类变量(static),而不包括实例变量,实例变量会在对象实例化时随着对象一块分配在Java堆中。
  2. 这里所设置的初始值通常情况下是数据类型默认的零值(如0、0L、null、false等),而不是被在Java代码中被显式地赋予的值。
  3. 如果类字段的字段属性表中存在 ConstantValue属性,即同时被final和static修饰,那么在准备阶段变量value就会被初始化为ConstValue属性所指定的值。

解析

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

标签:Java,字节,验证,虚拟机,阶段,机制,加载
From: https://www.cnblogs.com/xiaoovo/p/17352231.html

相关文章

  • 线程机制与事件机制
    进程与线程进程程序的一次执行--占有一片独有的内存空间可通过windows任务管理器查看进程线程进程内的一个独立执行单元是程序执行的一个完整流程是CPU的最小调度单位相关知识应用程序必须运行在某个进程的某个线程上一个进程中至少有一个运行的线程--主线程--进......
  • video标签如何加快加载速度
    视频标签(<video>)加载速度的优化可以从以下几个方面入手:压缩视频文件大小:可以使用视频压缩工具来压缩视频文件大小。压缩后的视频文件大小更小,加载速度更快。使用适当的视频格式:不同的浏览器支持不同的视频格式。因此,可以使用流行的视频格式,如MP4、WebM和Ogg,以确保视频在各种......
  • 【❀Java虚拟机】对象终止机制
    什么是对象终止机制?Java语言提供了对象终止( finalization)机制来允许开发人员提供对象被销毁之前的自定义处理逻辑处理。当垃圾回收器发现没有任何引用指向某个对象时,那么就会在垃圾回收中清除这个对象,在垃圾回收器回收此对象之前,会先调用这个对象的 finalize()方法。我们......
  • Cesium加载ArcGIS Server4490且orgin -400 400的切片服务
    Cesium在使用加载Cesium.ArcGisMapServerImageryProvider加载切片服务时,默认只支持wgs84的4326坐标系,不支持CGCS2000的4490坐标系。如果是ArcGIS发布的4490坐标系的切片服务,如果原点在orginX:-180.0Y:90.0的情况下,我们可以通过WebMapTileServiceImageryProvider按照WMTS的方式......
  • Java 反射机制的一个简单例子.
    一、什么是反射:反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。其中LEAD/LEAD++、Open......
  • 易基因:ChIP-seq等揭示热休克转录因子A1b调控植物高温胁迫响应的分子机制|应激反应
    大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 在拟南芥中,热休克转录因子A1b(HEATSHOCKTRANSCRIPTIONFACTORA1b,HSFA1b)通过影响种子产量来调控对环境胁迫的抗性。HSFA1b是生殖适应性的决定性因素,这种调控机制怎么形成的呢?2018年,英国生物-植物科学类期刊Journa......
  • Redis持久化机制
    Redis是内存数据库,但一旦服务器宕机,内存中的数据将全部丢失。作为缓存,虽然可以从慢速数据库重新读取数据,但是也会增加慢速数据库压力。所以选择数据持久化方式,避免从后端数据库中进行恢复3种持久化方式AOF:只追加文件(Append-OnlyFile)RDB:快照(snapshotting)RDB和AOF的混......
  • 硬件时钟和系统时钟的同步机制及案例分享
    由于技术能力有限,文章仅能进行简要分析和说明,如有不对的地方,请指正,谢谢......
  • spring的事务传播机制
    spring的事务传播机制嫌弃内容代码复杂的可直接看思维导图大纲即可基本概念指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行七种行为和测试PROPAGATION_REQUIRED默认,当前存在事务,则加入该事务;不存在事务,创建新事务。publicclassPropagationServi......
  • 容器云平台监控告警体系(五)—— Prometheus发送告警机制
    1、概述在Prometheus的架构中告警被划分为两个部分,在PrometheusServer中定义告警规则以及产生告警,Alertmanager组件则用于处理这些由Prometheus产生的告警。本文主要讲解Prometheus发送告警机制也就是在PrometheusServer中定义告警规则和产生告警部分,不过多介绍Alertmanager组......