JVM面试(三)类加载过程

news2024/9/20 7:53:48

什么是类加载?

前面的文章已经说过,我们手动敲代码,写出来的文件是.java文件。 虚拟机编译之后,可识别的文件是.class文件。

但是在真正运行的时候,在内存中进行各种流转,通过程序来进行执行的时候,应该 是遗传二进制字节流这种 类型的文件。

所以,我们可以认为加载过程是“将class文件加载为程序运行中可操作的对象”

本章呢,就是先分析一下整个类加载过程都有哪些动作,下一章再剖析一下类加载器以及双亲委派机制

什么时候进行类加载?

一个类型从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期将会经历加载
(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化
(Initialization)、使用(Using)和卸载(Unloading)七个阶段,其中验证、准备、解析三个部分统称为连接(Linking)。这七个阶段的发生顺序如图:
在这里插入图片描述
加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的。但是解析阶段有可能是在初始化阶段之后开始的,是为了Java语言运行时绑定特性。

关于具体什么情况下开始“加载”,《Java虚拟机规范》中并没有强制约束。

但是!对于“初始化”阶段,《Java虚拟机规范》严格规定了有且只有六种情况必须对类进行“初始化”。
而“加载”,“验证”,“准备”都要在初始化之前,所以也就相当于变相的规定了“加载”的开始。也就是下面六种情况

  1. 遇到new、getstatic、putstatic或invokestatic这四条字节码指令时,如果类型没有进行过初始化,则需要先触发其初始化阶段。
  2. 使用java.lang.reflect包的方法对类型进行反射调用的时候,如果类型没有进行过初始化,则需要先触发其初始化。
  3. 当初始化类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
  4. 当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。
  5. 当使用JDK 7新加入的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果为REF_getStatic、REF_putStaticREF_invokeStatic、REF_newInvokeSpecial四种类型的方法句柄,并且这个方法句柄对应的类没有进行过初始化,则需要先触发其初始化。
  6. 当一个接口中定义了JDK 8新加入的默认方法(被default关键字修饰的接口方法)时,如果有这个接口的实现类发生了初始化,那该接口要在其之前被初始化。

类加载过程

加载阶段

“加载”(Loading)阶段是整个“类加载”(Class Loading)过程中的一个阶段,希望读者没有混淆
这两个看起来很相似的名词。在加载阶段,Java虚拟机需要完成以下三件事情:

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

加载阶段结束后,Java虚拟机外部的二进制字节流就按照虚拟机所设定的格式存储在方法区之中了,方法区中的数据存储格式完全由虚拟机实现自行定义,《Java虚拟机规范》未规定此区域的具体数据结构。类型数据妥善安置在方法区之后,会在Java堆内存中实例化一个java.lang.Class类的对象,这个对象将作为程序访问方法区中的类型数据的外部接口。

验证阶段

验证是连接阶段的第一步,这一阶段的目的是确保Class文件的字节流中包含的信息符合《Java虚拟机规范》的全部约束要求,保证这些信息被当作代码运行后不会危害虚拟机自身的安全。

  • 文件格式验证(校验文件是否规范,class文件各个部分是否完整等等)
  • 元数据验证(是否存在父类,是否为抽象类,是否与父类产生冲突矛盾,主要进行语义校验)
  • 字节码验证(一个是校验代码是否会篡改计算机底层逻辑,是否安全;另一方面是校验数据类型等等 信息)
  • 符号引用验证(主要确保各个名称是否能找到对应类,类中的字段方法等信息是否可以正常使用)

准备阶段

主要为类中定义的变量(静态变量,static修饰的变量),分配内存并且设置类变量初始阶段。
要注意,这里只有类变量,不包括实例变量。实例变量会随着对象的实例化一起分配在Java堆中。

解析

笼统来说,是Java虚拟机将常量池中的“符号引用”替换为“直接引用”的过程。
这块内容我们后面要单开一章来进行讲解,这里就简单说一下两个的关联。

  • 符号引用:以一组符号来描述所引用的目标,与内存布局无关,只要可以指代目标就可以。
  • 直接引用:直接指向目标的一个指针,与内存布局相关,必须是目标已经在虚拟机中存在的。

并且解析动作还有不同的类型,用来处理不同的数据。
主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符这7类符号引用进行

初始化

类的初始化阶段是类加载过程的最后一个步骤,之前介绍的几个类加载的动作里,除了在加载阶段用户应用程序可以通过自定义类加载器的方式局部参与外,其余动作都完全由Java虚拟机来主导控制。直到初始化阶段,Java虚拟机才真正开始执行类中编写的Java程序代码,将主导权移交给应用程序。

可以理解为,初始化阶段就是执行类的构造器方法的过程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2100971.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深度解析】GPT-3.5、GPT-4.0、GPT-4o mini的区别,你了解多少?

在人工智能的浪潮中,GPT系列模型如同璀璨的明星,吸引着无数开发者和研究者的目光。随着技术的不断进步,OpenAI推出了多个版本的GPT模型,其中GPT-3.5、GPT-4.0、GPT-4o mini各具特色。今天,我们就来深入探讨它们之间的区…

Odoo:开源免费的OMS订单管理系统

企业全渠道订单管理服务平台 开源智造Odoo免费开源ERP全渠道订单管理应用包含渠道分销订单、零售订单、电商订单、直销订单四部分,主要服务于核心企业的渠道信息化管理,帮助企业从传统分销向移动互联、电商直销或渠道数字化订货转型、新零售转型&#xf…

笔记 10 : 彭老师课本第 5 章 , GPIO , vim 的复制剪切删除 ; uboot读写内存的 md , nm 命令

(77) 进入代码实验以来,开始有机会频繁的修改源代码。补充 vim 的使用: (78) 如何只查看某个文件的权限,属性: (79) 关于 rm 命令: (…

【netty系列-09】深入理解和解决tcp的粘包拆包

Netty系列整体栏目 内容链接地址【一】深入理解网络通信基本原理和tcp/ip协议https://zhenghuisheng.blog.csdn.net/article/details/136359640【二】深入理解Socket本质和BIOhttps://zhenghuisheng.blog.csdn.net/article/details/136549478【三】深入理解NIO的基本原理和底层…

C#——XML序列化

开发环境 VS2022 .net core 6.0 序列化概念 序列化是将内存中的对象或者对象图(一组相互引用的对象)拉平为一个可以保存或进行传输的字节流,或者XML节点。反序列化正好相反,它把数据流重新构造成内存中的一个对象或者对象图。…

【位运算】--- 进阶题目赏析

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏: 算法Journey 本节我们来赏析位运算的一些进阶题目。 🏠 只出现一次的数字II 📌 题目解析 只出现一次的数字II 📌 算…

Anylogic制作界面元素tips

点击元素后跳转至其他视图,且能够把某个共同元素移植过去 navigate( viewStatistics2 ); groupControls.setX( groupControls.getX() 1200 );

python-笨小猴

题目描述 笨小猴的词汇量很小,所以每次做英语选择题的时候都很头疼。但是他找到了一种方法,经试验证明,用这种方法去选择选项的时候选对的几率非常大! 这种方法的具体描述如下:假设maxn是单词中出现次数最多的字母的出…

kafka3.7.1 单节点 KRaft部署测试发送和接收消息

一、环境准备 kafka3.7.1 包下载地址: https://mirrors.nju.edu.cn/apache/kafka/3.7.1/kafka_2.13-3.7.1.tgz openjdk11.0.2 下载地址: https://mirrors.nju.edu.cn/openjdk/11.0.2/openjdk-11.0.2_linux-x64_bin.tar.gz 二、openjdk 安装 【如已安装…

设计模式学习-简单的命令模式例子

上一章节介绍过了命令模式,这一篇文章就简单的做一个小案例来巩固学习 搭建场景 简单的搭建一个场景就行 ,随便准备一个物体放在场景中位置Reset一下即可。 代码编写 定义接口(或者抽象类)ICommand 用来规范Command的行为。注意…

在线音乐播放器项目

在线音乐播放器项目 登录页面 注册页面 主页 上传文件 我的喜欢 前端 js html css 三剑客 后端 Spring Boot框架 插件有:Spring Boot DevTools、Lombok、Spring Web、MySQL Driver、MyBatis Framework、security、detect 数据库有 三张表 lovemusic、music、user 工具类( co…

pycharm的Structure是什么,怎么打开,每个图标的功能是什么

一、Structure的含义 在PyCharm中,Structure是一个非常有用的功能,它可以帮助开发者快速浏览和理解当前文件的代码结构,Structure视图通过不同的图标来表示代码中的不同元素。 二、如何打开Structure功能 在windows上可以通过Alt7来打开St…

VsCode + Go + macOS 小白 demo运行

1. 安装:brew install go 2. 设置工作目录和代理 ​ go env -w GOPATH/Users/niu/code/goexport GOPROXYhttps://goproxy.cngo env -w GO111MODULEongo env 查看上面三个值是否和设置的一样​ 3. 安装vscode. go插件 4. vscode打开GOPATH设置的工作目录 command…

ESP32无线WiFi芯片模组,设备物联网连接通信,产品智能化交互升级

在数字化浪潮的推动下,我们正步入一个万物互联的新时代。物联网(IoT)技术,作为连接物理世界与数字世界的桥梁,正逐渐渗透到我们生活的每一个角落。 乐鑫正通过其创新的无线WiFi芯片模组,为这些领域的发展提…

Linux动态监控系统

目录 动态监控进程 介绍 基本语法 选项说明 交互操作说明 应用实例 动态监控进程 介绍 top指令类似于ps命令,只是top在执行一段时间可以更新正在运行的进程。 基本语法 选项说明 负载那三个值加起来除以三若大于零点7就说明负载较大 ,buff是占用…

全网最全的安服工程师修炼手册

全网最全安服工程师修炼手册 本篇文章主要介绍安全服务工程师的必备技能,也是简单记录下我的安服历程! 思维导图附上 点击下载 基础技能 网络 IP IP概念:IP地址被用来给Internet上的电脑一个编号。日常见到的情况是每台联网的PC上都需要…

Faiss向量数据库

Faiss(Facebook AI Similarity Search)向量数据库是由Facebook AI研究院开发的一种高效相似性搜索和聚类的库。Faiss不仅支持在高维空间中进行高效的相似性搜索,还能够在处理大规模数据集时展现出卓越的性能,尤其适用于图像检索、…

C# SM2 SM3 SM4 使用

目录 效果 SM2 SM3 SM4 项目 代码 SM2Utils.cs Sm3Utils.cs Sm4Utils.cs 下载 效果 SM2 公钥:04ca3e272e11b5633681cb0fbbfd8c162be08918ce5b644cd33d49c17be8674caf6c20a11de8b65333924dfe7d42246abb4a4c36b663bef1aafc624a35acf4d2b1 私钥:…

多个视频怎么合成一个视频?这10款视频合并软件大家都在用,适合手机和电脑!

如果您希望利用拍摄的片段制作出色的电影或视频故事,选择合适的视频合并软件是非常关键的。此外,视频剪辑的复杂程度可能会让人感到意外,有时简单得让人吃惊。专业的视频剪辑合并大师能够大大简化视频合并的过程,这正是它们的价值…

『功能项目』主角的信息显示【16】

本章项目成果展示 我们打开上一篇15怪物的信息显示的项目, 本章要做的事情是对主角的UI信息实时显示 创建一个脚本:UIManager.cs 创建一个空物体作为钉子钉在左上角命名为LeftUp 创建Image做为头像 将以下资源导入Art文件夹 将以下资源图片放至Art文件夹…