当前位置: 首页 > news >正文

【JVM】Java类的加载机制!

一、类的生命周期

类加载过程包含:加载验证准备解析初始化 ,一共包括5 个阶段。

(1)加载:

简单来说就是将java类的字节码文件加载到机器内存中。在加载类时,Java虚拟机必须完成以下3件事情: 

  • 通过类的完全限定名称获取定义该类的二进制字节流。
  • 将该字节流表示的静态存储结构转换为Metaspace元空间区的运行时存储结构。
  • 在内存中生成一个代表该类的 Class 对象,作为元空间区中该类各种数据的访问入口。

(2)验证:

确保 Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

(3)准备:

为类的静态分配内存,并将其初始化为默认值当一个类验证通过时,虚拟机就会进入准备阶段。在这个阶段,虚拟机就会为这个类分配相应的内存空间,并设置默认初始值。Java虚拟机为各类型变量默认的初始值如表所示。

类型

默认初始值

byte

0

short

0

int

0

long

0L

float

0.0f

double

0.0

char

\u0000

boolean

false

reference

null

没有对static fianl修饰的变量进行赋值,因为final修饰的变量已经在编译阶段就进行了赋默认值,而在准备阶段进行的是显式赋值 

(4)解析:

将常量池的符号引用替换为直接引用的过程。其中解析过程在某些情况下可以在初始化阶段之后再开始,这是为了支持 Java 的动态绑定。

符号引用就是一些自变量的引用,和虚拟机的内部数据结构和和内存布局无关。比较容易理解的就是在Class类文件中,通过常量池进行了大量的符号引用。但是在程序实际运行时,只有符号引用是不够的,比如当如下println()方法被调用时,系统需要明确知道该方法的位置。

(5)初始化:

初始化阶段才真正开始执行类中定义的 Java 程序代码。初始化阶段是虚拟机执行类构造器 <clinit>()方法的过程

对于<clinit>()方法的调用,也就是类的初始化,虚拟机会在内部确保其多线程环境中的安全性。

虚拟机会保证一个类的()方法在多线程环境中被正确地加锁、同步,如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的<clinit>()方法,其他线程都需要阻塞等待,直到活动线程执行<clinit>()方法完毕。

正是因为函数<clinit>()带,因此,如果在一个类的<clinit>()方法中有耗时很长的操作,就可能造成多个线程阻塞,引发死锁。并且这种死锁是很难发现的,因为看起来它们并没有可用的锁信息。

如果之前的线程成功加载了类,则等在队列中的线程就没有机会再执行<clinit>()方法了。那么,当需要使用这个类时,虚拟机会直接返回给它已经准备好的信息。

二、类加载的主动引用和被动引用 

(1)主动引用(会发生初始化)

  1.  遇到new、getstatic、putstatic、invokestatic这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。
  2. 使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
  3. 加载一个类,如果其父类还未加载,则先触发该父类的加载。
  4. 当虚拟机启动时,用户需要定义一个要执行的主类 (包含 main() 方法的类),虚拟机会先加载这个类。
  5. 当一个接口中定义了 JDK8 新加入的默认方法(被 default 关键字修饰的接口方法)时,如果有这个接口的实现类发生了加载,则该接口要在实现类之前被加载。

(2)被动引用(看上去会,其实不会发生初始化):

  1. 通过子类引用父类的静态字段,不会导致子类初始化
  2. 通过数组定义类引用类,不会触发此类的初始化
  3. 常量在编译阶段会存入调用类的常量池中,本质上没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化

三、类加载器

类加载器是Java虚拟机中的一个子系统,用于将类的字节码文件加载到内存中,并转换为Java的类对象。Java虚拟机需要根据类的全名来定位并加载类的字节码文件,而类加载器负责从文件系统、网络等位置查找类文件,并加载到Java虚拟机中。

Java虚拟机中有三种类加载器,分别是启动类加载器、扩展类加载器和应用程序类加载器。

(1)Bootstrap ClassLoader:启动加载器

它负责加载Java的核心类(如String、System等)。它比较特殊,因为它是由原生C++代码实现的,并不是java.lang.ClassLoader的子类。启动类加载器无法被 Java 程序直接引用,所以下面的运行结果为null:

(2)Extension ClassLoader:扩展类加载器

它负责加载JRE的扩展目录(%JAVA_HOME%/jre/lib/ext)中JAR包的类,我们可以通过把自己开发的类打包成JAR文件放入扩展目录来为Java扩展核心类以外的新功能。

(3)System ClassLoader(或Application ClassLoader):应用程序(系统)类加载器

它负责在JVM启动时加载来自Java命令的-classpath选项、java.class.path系统属性,或CLASSPATH环境变量所指定的JAR包和类路径。程序可以通过ClassLoader的静态方法getSystemClassLoader来获取系统类加载器:

四. 对象的创建过程

Step1:类加载检查

虚拟机遇到一条 new 指令时,首先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已被加载过、解析和初始化过。如果没有,那必须先执行相应的类加载过程。

Step2:分配内存

类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完成后便可确定,为对象分配空间的任务等同于把一块确定大小的内存从 Java 堆中划分出来。内存分配的查找方式“指针碰撞”“空闲列表” 两种。

Step3:初始化零值

内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头),这一步操作保证了对象的实例字段在 Java代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。

Step4:设置对象头

初始化零值完成之后,虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的 GC 分代年龄等信息。 这些信息存放在对象头中 另外,根据虚拟机当前运行状态的不同,如是否启用偏向锁等,对象头会有不同的设置方式。

Step5:执行 init 构造方法

在上面工作都完成之后,从虚拟机的视角来看,一个新的对象已经产生了,但从Java 程序的视角来看,对象创建才刚开始,<init> 构造方法还没有执行,目前所有的字段都还为零。所以一般来说,执行 new 指令之后会接着执行 <init> 构造方法,把对象按照程序逻辑的意愿进行初始化,这样一个真正可用的对象才算完整创建出来。

相关文章:

【JVM】Java类的加载机制!

一、类的生命周期 类加载过程包含&#xff1a;加载、验证、准备、解析和初始化 &#xff0c;一共包括5 个阶段。 &#xff08;1&#xff09;加载&#xff1a; 简单来说就是将java类的字节码文件加载到机器内存中。在加载类时&#xff0c;Java虚拟机必须完成以下3件事情&…...

Postman使用_接口导入导出

文章目录 Postman导入数据Collections导出数据Environments导出数据Postman导出所有数据 Postman导入数据 可以导入collections&#xff08;接口集&#xff09;、Environments&#xff08;环境配置&#xff09;通过分享的链接或导出的JSON文件导入数据&#xff08;还可以从第三…...

linux下centos7升级python版本

由于项目需要使用爬虫&#xff0c;爬虫框架支撑3.8以上版本。而linux自带的python版本是2.7.*&#xff0c;所以需要升级python版本至3.8 键脚本安装Python3.6-Python3.10 bash <(curl -sSL https://raw.githubusercontent.com/midoks/choose-linux-python/main/install.sh…...

Python空值None的意义

在 Python 中&#xff0c;有一个特殊的常量 None&#xff08;N 必须大写&#xff09;。和 False 不同&#xff0c;它不表示 0&#xff0c;也不表示空字符串&#xff0c;而表示没有值&#xff0c;也就是空值。 这里的空值并不代表空对象&#xff0c;即 None 和 [] 以及 "&q…...

什么是无线传输技术,如Wi-Fi、蓝牙和NFC的特点和应用场景

1、什么是无线传输技术&#xff0c;如Wi-Fi、蓝牙和NFC的特点和应用场景。 无线传输技术是指通过无线电波进行数据传输的技术。Wi-Fi、蓝牙和NFC都是常见的无线传输技术&#xff0c;它们的特点和应用场景如下&#xff1a; Wi-Fi&#xff1a;Wi-Fi是一种基于802.11协议的无线传…...

RUST 每日一省:全局变量

Rust中允许存在全局变量。它们一般有两种&#xff1a;常数和静态值。 常量 我们使用关键字 const 来创建常量。由于常量未使用关键字 let 声明&#xff0c;因此在创建它们时必须指定类型。常量只能进行简单赋值&#xff0c;并且没有固定的内存地址&#xff0c;无论它们在何处使…...

Arduino与Proteus仿真-WiFi网络仿真环境搭建

Arduino与Proteus网络(WiFi)仿真环境搭建 文章目录 Arduino与Proteus网络(WiFi)仿真环境搭建1、软件准备2、硬件准备3、仿真电路原理图4、仿真代码实现5、仿真结果本文将详细介绍如何在Proteus搭建Arduino的WiFi仿真环境。 1、软件准备 1)Arduino IDE或 VSCode + PlatformIO …...

陪诊系统|陪诊软件革新医疗体验

随着科技的不断发展&#xff0c;陪诊小程序逐渐成为医疗行业中一股强大的力量&#xff0c;为患者和医护人员带来了前所未有的便捷和效益。作为一种创新的医疗服务工具&#xff0c;陪诊小程序在提升患者体验、优化医疗流程方面发挥着重要的作用。让我们一起来了解一下陪诊小程序…...

零基础Linux_5(开发工具_上)yum和vim和gcc/g++和gdb

目录 1. 软件包管理器 yum 1.1 安装软件的方式 1.2 yum 指令 2. vim&#xff08;编辑器&#xff09; 2.1 vim 的简单操作 2.1.1 方向键&#xff08;HJKL&#xff09; 2.1.2 退出 vim 2.2 vim 文本批量化操作(命令模式) 2.2.1 复制.粘贴.删除.剪贴.撤销 2.2.2 光标跳转…...

mysql建表的时候设置默认值为null会对存储和索引有影响吗?

在MySQL中&#xff0c;将字段的默认值设置为NULL在建表时对存储和索引可能会产生一些影响&#xff0c;具体取决于数据类型、索引设计和查询模式等因素。以下是可能的影响&#xff1a; 存储空间&#xff1a;如果将默认值设置为NULL&#xff0c;并且该字段允许存储NULL值&#xf…...

通过API爬取到的淘宝商品详情数据展示(api测试入口)

API名称&#xff1a;item_get 响应数据 item: { num_iid: "698291711589", title: "美洋MEIYANG【现货】大嫂的西装 内有乾坤率性撞色TR垫肩直筒西服", desc_short: "", price: 439.12, total_price: 0, suggestive_price: 0, orginal_price: …...

蓝桥杯2023年第十四届省赛真题-买瓜--题解

目录 蓝桥杯2023年第十四届省赛真题-买瓜 题目描述 输入格式 输出格式 样例输入 样例输出 提示 【思路解析】 【代码实现】 蓝桥杯2023年第十四届省赛真题-买瓜 时间限制: 3s 内存限制: 320MB 提交: 796 解决: 69 题目描述 小蓝正在一个瓜摊上买瓜。瓜摊上共有 n 个…...

python萌新爬虫学习笔记【建议收藏】

文章目录 1. 如何何请求解析url2. 如何获取标签里面的文本3. 如何解析JSON格式4. 如何添加常用的header5. 如何合并两个div6. 如何删除html dom的部分结构7. 如何一次性获取所有div标签里的文本8. python爬虫如何改变响应文本字符集编码9. 如何进行字符集转码11. response.text…...

网络编程——基础知识

全文目录 网络发展协议OSI七层模型TCP/IP五层(或四层)模型 网络传输网络地址IP地址MAC地址 网络通信的本质 网络发展 网络没有出来之前计算机都是相互独立的&#xff1a; 网络就是将独立的计算机连接在一起&#xff0c;局域网和广域网的区别只是范围上的大小&#xff1a; 局域…...

flutter聊天界面-TextField输入框实现@功能等匹配正则表达式展示高亮功能

flutter聊天界面-TextField输入框实现功能等匹配正则表达式展示高亮功能 一、简要描述 描述&#xff1a; 最近有位朋友讨论的时候&#xff0c;提到了输入框的高亮展示。在flutter TextField中需要插入特殊样式的标签&#xff0c;比如&#xff1a;“请 张三 回答一下”&#x…...

【C语言】指针的进阶(二)—— 回调函数的讲解以及qsort函数的使用方式

目录 1、函数指针数组 1.1、函数指针数组是什么&#xff1f; 1.2、函数指针数组的用途&#xff1a;转移表 2、扩展&#xff1a;指向函数指针的数组的指针 3、回调函数 3.1、回调函数介绍 3.2、回调函数的案例&#xff1a;qsort函数 3.2.1、回顾冒泡排序 3.2.1、什么是qso…...

Java集合之HashSet接口

Set Set接口、HashSet类、TreeSet类 Set&#xff08;组、集&#xff09;&#xff1a;表示无序&#xff0c;元素不能重复的集合&#xff0c;组中的元素必须唯一 Set接口 Set接口定义了组/集/集合&#xff08;Set&#xff09;。他扩展了Collection接口&#xff0c;并声明了不允…...

uniapp----微信小程序 日历组件(周日历 月日历)【Vue3+ts+uView】

uniapp----微信小程序 日历组件&#xff08;周日历&& 月日历&#xff09;【Vue3tsuView】 用Vue3tsuView来编写日历组件&#xff1b;存在周日历和月日历两种显示方式&#xff1b;高亮显示当天日期&#xff0c;红点渲染有数据的日期&#xff0c;点击显示数据 1. calenda…...

【记录】深度学习环境配置(pytorch版)

1080面对Transformer连勉强也算不上了&#xff0c;还是要去用小组的卡 完整记一个环境配置&#xff0c;方便后面自用✍️ 目前要简单许多&#xff0c;因为显卡驱动已经装好&#xff0c;后安装的库版本与其对应即可。 nvidia-smi查看GPU信息 ** CUDA版本12.2 conda -V查询conda…...

如何将项目推送到GitHub中

将项目推送到 GitHub 仓库并管理相关操作&#xff0c;遵循以下步骤&#xff1a; 创建 GitHub 账户&#xff1a;如果您没有 GitHub 账户&#xff0c;首先需要在 GitHub 官网 上创建一个账户。 创建新仓库&#xff1a;在 GitHub 页面上&#xff0c;点击右上角的加号图标&#xf…...

202X年CSDN年度技术趋势大预测

好的&#xff0c;以下是一篇关于CSDN年度技术趋势预测的技术文章大纲&#xff1a;202X年CSDN年度技术趋势预测&#xff1a;引领未来的技术变革一、引言技术发展的加速与变革年度技术趋势对行业的影响本文预测的依据与方法论二、人工智能与生成式AI的深化应用大模型技术的演进方…...

如何在3分钟内完成Windows与Office智能激活:KMS_VL_ALL_AIO完全指南

如何在3分钟内完成Windows与Office智能激活&#xff1a;KMS_VL_ALL_AIO完全指南 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 还在为Windows操作系统和Office办公软件的正版激活而烦恼吗&…...

独立开发者如何借助taotoken模型广场低成本验证产品创意

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 独立开发者如何借助Taotoken模型广场低成本验证产品创意 对于资源有限的独立开发者或小型工作室而言&#xff0c;验证一个需要AI功…...

Python 爬虫数据处理:特殊格式文档爬虫解析处理

前言 在 Python 爬虫规模化采集业务中&#xff0c;除常规 HTML 网页与 JSON 接口数据外&#xff0c;经常会遇到各类非网页型特殊格式文档资源&#xff0c;常见包含 PDF、Word、Excel、CSV、TXT、压缩包内嵌文档、Base64 加密文档、富文本混合格式文档等。这类文档无法通过常规…...

紧急预警:Midjourney即将下架Nihonga相关风格标签?(内部消息+已存档的5类不可再生提示词组合,仅限今日开放获取)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Nihonga风格在Midjourney中的历史定位与美学内核 Nihonga&#xff08;日本画&#xff09;作为明治维新后确立的现代民族绘画体系&#xff0c;以天然矿物颜料、金箔银箔、胶质媒介及传统和纸为物质基础&…...

深入理解STM32的FSMC:如何像操作SRAM一样轻松点亮你的TFTLCD屏幕

深入理解STM32的FSMC&#xff1a;如何像操作SRAM一样轻松点亮你的TFTLCD屏幕 在嵌入式开发领域&#xff0c;TFTLCD屏幕的驱动一直是让开发者又爱又恨的难题。传统的GPIO模拟时序方式虽然简单直接&#xff0c;但在高分辨率屏幕和复杂应用场景下往往力不从心。这时&#xff0c;S…...

打破高频、高速四种材料混压

打破高频、高速四种材料混压&#xff0c;铸就PCB行业硬核实力。在航空航天领域&#xff0c;每一次技术的突破都意味着对材料与工艺的极致追求。今天&#xff0c;我们要聊的这款产品&#xff0c;堪称多材料混压天花板&#xff0c;——16层、四种材料混压、三次压合、板厚5.0mm、…...

拾亩绿光纯亚麻籽微粉效果怎么样

很多人想通过亚麻籽补充营养&#xff0c;却常遇到传统亚麻籽难吸收、营养易流失的问题&#xff1a;直接嚼咽口感粗糙&#xff0c;普通研磨粉冲调结块&#xff0c;榨油后Omega-3等核心营养大量损耗。拾亩绿光纯亚麻籽微粉依托南京国英健康科技有限公司的专利技术&#xff0c;可解…...

GitHub 代码提交常见问题及解决指南

摘要本文聚焦 GitHub 代码提交流程&#xff0c;围绕本地文件上传、远程仓库关联、分支推送等核心操作&#xff0c;梳理常见报错&#xff08;如可疑所有权、分支不匹配、协议不支持等&#xff09;&#xff0c;解析错误成因并提供分步解决方法&#xff0c;覆盖 Git 命令执行、仓库…...

软件测试行业的结构性变化:外包测试正在消失,高端测试供不应求

一个正在被重新定义的职业 如果你是一位在软件测试领域工作了三到五年的从业者&#xff0c;大概率会在某个加班的深夜产生过这样的困惑&#xff1a;为什么招聘网站上“功能测试工程师”的岗位越来越少&#xff0c;薪资也停滞不前&#xff1f;为什么同事群里讨论的不再是如何设…...