【JVM】类加载

news2024/11/24 8:33:17

类加载

  • 一. 加载 Loading
  • 二. 连接 Linking
    • 1. 验证 Verification
    • 2. 准备 Preparation
    • 3. 解析 Resolution
  • 三. 初始化 Initialization

类加载是运行时环境的一个重要核心功能。
类加载的主要功能:把 .class 文件加载到内存中构建成为类对象。

什么时候会进行类加载呢 ?
不是说 java 程序一运行,就把所有的类都加载了,而是用到的时候再加载。(懒汉模式)

那什么时候算是用到了呢 ?

  1. 创建类的实例
  2. 调用类的静态方法 / 静态属性
  3. 加载子类,就会先加载父类

类的生命周期是这样的:

在这里插入图片描述

其中前 5 步是固定的顺序并且也是类加载的过程,其中 中间的 3 步都属于连接,所以对于类加载来
说总共分为以下几个步骤:

  1. 加载 Loading
  2. 连接 Linking:
    验证 Verification
    准备 Preparation
    解析 Resolution
  3. 初始化 Initialization

下面我们分别来看每个步骤的具体执行内容。

一. 加载 Loading

“加载”(Loading)阶段是整个“类加载”(Class Loading)过程中的一个阶段,在加载 Loading 阶段,Java虚拟机需要完成以下三件事情:

  1. 通过一个类的全限定名来获取定义此类的二进制字节流 (.class 文件)。
  2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。虚拟机会将类文件的二进制字节流解析并转化为方法区
    (Java 8之后称为元空间 Metaspace)中的运行时数据结构。这些数据结构包括类的字段、方法、父类、接口、常量池等信息。
  3. 在第2步之后,虚拟机会创建一个 java.lang.Class 对象,用于表示刚刚加载的类。这个java.lang.Class对象包含了对类的引用、方法区数据结构的指针等,它是在Java程序中访问类元信息的入口。这个对象的生成是为了让Java程序能够在运行时通过反射等手段访问和操作加载的类。

.class 文件就是把 .java 文件中核心信息都表达出来,只不过组织格式发生了变化。
Loading 会把从 .class 文件中解读到的信息初步填写到类对象中。

二. 连接 Linking

1. 验证 Verification

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

验证选项:

  • 文件格式验证
  • 字节码验证
  • 符号引用验证…

如果不符合规范类加载就会失败,抛出异常。

2. 准备 Preparation

准备阶段是正式为类中定义的变量(即静态变量,被static修饰的变量)分配内存并设置类变量初始值的阶段。
注意这里面设置的初始值指的是默认值
比如此时有这样一行代码:

public static int value = 123;

它是初始化 value 的 int 值为 0,而非 123。

3. 解析 Resolution

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

注意:常量池中不是只有 字符串常量

运行时常量池: 存放字面量与符号引用。

  • 字面量 : 字符串常量 (JDK 8 移动到堆中) 、final常量、基本数据类型的值。
  • 符号引用 : 类和结构的完全限定名、字段的名称和描述符、方法的名称和描述符。

举个栗子:

class Example {
    public int count = 0;
    public void increment() {
        count++;
    }
}

public class Main {
    public static void main(String[] args) {
    	Example e = new Example();
        int currentCount = e.count; // 引用Example类的count字段
        e.increment(); // 调用Example类的increment方法
    }
}
  • 解析 e.count:在这个步骤中,虚拟机将符号引用 e.count 解析为实际的内存地址,以便能够访问count字段的值。

  • 解析 e.increment():虚拟机将符号引用 e.increment() 解析为实际的方法内存地址,以便能够正确地调用increment方法。

到这里, 你可能有些疑惑 ?这个实例属性 count 不是在运行阶段创建对象时才分配空间 ?但是类加载阶段不是先于运行阶段么 ?

  • 确实,Resolution 阶段的主要任务是将符号引用替换为实际的直接引用,但这些直接引用在Resolution 阶段只是一种占位符,它们在内存中并不代表实际的对象或实例属性。
  • 直到对象实例化时,实例属性的内存空间才是真正有效的,并且可以存储实际的属性值。Resolution 阶段的替换只是为了确保在运行时可以正确地引用这些属性,但不会创建对象实例或分配实例属性的内存空间。

这个分离的设计有助于节省内存和提高性能,因为不是所有类都会被实例化,只有在需要时才会分配内存。

但是对于类名, 方法名, 静态属性的符号引用替换为直接引用是没有这个问题的。

三. 初始化 Initialization

执行类的静态初始化。在类首次被主动使用(例如,创建对象实例、访问静态字段或调用静态方法)时触发。
在这个阶段,虚拟机会初始化类中的静态字段和静态代码块,确保它们按照指定的顺序被正确地初始化。

此时上述的代码:

public static int value = 123;

此时 value 的值才是 123.

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

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

相关文章

9月第4周榜单丨哔哩哔哩飞瓜数据B站UP主排行榜发布!

飞瓜轻数发布2023年9月18日-9月24日飞瓜数据UP主排行榜(B站平台),通过充电数、涨粉数、成长指数、带货数据等维度来体现UP主账号成长的情况,为用户提供B站号综合价值的数据参考,根据UP主成长情况用户能够快速找到运营能…

docker openjdk:8-jdk-alpine 修改时区、添加字体

新建Dockerfile文件,制作新镜像 FROM openjdk:8-jdk-alpine 1、解决字体问题 RUN apk add --update ttf-dejavu fontconfig && rm -rf /var/cache/apk/* 2、解决时差问题 # 解决时差8小时问题ENV TZAsia/ShanghaiRUN ln -snf /usr/share/zoneinfo/$TZ /et…

Mybatisplus条件构造器

一、Wrapper介绍 Wrapper : 条件构造抽象类,最顶端父类 AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件 QueryWrapper : 查询条件封装UpdateWrapper : Update 条件封装AbstractLambdaWrapper…

推动教育行业数字化转型,开利网络为AI熊教育提供落地服务

随着新兴技术的飞速发展,新产品、新服务和新商业模式正不断涌现,推动市场格局逐渐改变。对于传统企业来说,企业发展不仅面临行业内部的竞争,还面临跨界竞争者和颠覆性竞争者的挑战,充满着不确定性。开利网络服务客户AI…

综述 | 关于点云配准的全面综述(一)

原创 | 文 BFT机器人 01 摘要 配准是两个点云之间的变换估计问题,在众多计算机视觉应用中具有独特且关键的作用。基于优化的方法和深度学习方法的发展提高了配准的鲁棒性和效率。最近,基于优化和深度学习方法的结合进一步提高了性能。然而,…

2009款一汽马自达6车自适应前照灯及车身稳定系统功能异常关闭

故障现象 一辆2009款一汽马自达6车,搭载L5发动机,累计行驶里程约为10.7万km。该车组合仪表上的自适应前照灯功能关闭(AFS OFF)指示灯、动态稳定系统功能关闭(DSC OFF)指示灯及防侧滑指示灯异常点亮。 故障诊…

FragmentManager is already executing transactions

本文解决问题: java.lang.IllegalStateException: FragmentManager is already executing transactions 问题背景描述: 在Fragment中 用tablayoutviewpagerfragment,即Fragment嵌套Fragment场景、或者ViewPager2嵌套ViewPager2时。 执行生命…

【Linux】之Centos7卸载KVM虚拟化服务

👨‍🎓博主简介 🏅云计算领域优质创作者   🏅华为云开发者社区专家博主   🏅阿里云开发者社区专家博主 💊交流社区:运维交流社区 欢迎大家的加入! 🐋 希望大家多多支…

​从零开始:集成视频直播美颜SDK到直播平台的步骤

当下,实时美颜技术在直播、社交领域中扮演了关键的角色,帮助主播增强自信,吸引更多观众。本文将指导您从零开始,逐步了解如何将视频直播美颜SDK集成到您的直播平台中。 第一步:选择适用的美颜SDK 在集成美颜功能之前…

什么是OSPF?为什么需要OSPF

【微|信|公|众|号:厦门微思网络】 【微思网络www.xmws.cn,成立于2002年,专业培训21年,思科、华为、红帽、ORACLE、VMware等厂商认证及考试,以及其他认证PMP、CISP、ITIL等】 什么是OSPF? 开放式最短路径优…

适合企业的跨隔离网文件摆渡的四种方式及优缺点

在当今的信息化时代,数据是企业的重要资产,如何有效地管理和传输数据,尤其是跨隔离网的大文件数据,是企业面临的一个挑战。跨隔离网文件摆渡是指在不同安全等级或网络环境的计算机之间传输文件的过程。 目前,市场上常见…

修改Jenkins主目录

Windows系统上安装了Jenkins后,默认数据目录,也就是工作区目录,即:每次构建的项目数据文件所在目录为: 随着构建项目的增多,一直用这个目录,C盘东西越来越多,电脑就会越来越卡&#…

Firefox 开发团队对 Vue 3 进行优化效果显著

Mozilla 官方博客近日发表文章《Faster Vue.js Execution in Firefox》,介绍了 Firefox 开发团队对 Vue 3 进行的优化。 文章写道,在使用 Speedometer 3 对 Firefox 进行基准测试时,他们发现 Vue.js test 的测试结果从 Vue 2 升级到 Vue 3 后…

第九章 动态规划 part11 123. 买卖股票的最佳时机III 188. 买卖股票的最佳时机IV

第五十天| 第九章 动态规划 part11 123. 买卖股票的最佳时机III 188. 买卖股票的最佳时机IV 一、123. 买卖股票的最佳时机III(难难难难难) 题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii/ 题目介绍&#xff…

如何将 Python 运用到实际的测试工作中

1、自动化测试脚本编写: Python广泛用于编写自动化测试脚本,以执行各种测试任务。可以使用Selenium、Appium或PyTest等库来辅助测试脚本的编写。 下面是一个示例: from selenium import webdriver import unittestclass LoginTest(unittes…

每个测试人都会遇到的批量安装,你真的会操作吗?

♥ 前 言 能不能通过脚本来实现多台设备同时安装 App? 实现过程 核心技术解决方案: adb 命令 多进程/多线程 采用的脚本语言: Java、Python、Shell、bat 都可 因为 Shell 与 bat 直接可以与 adb 命令交互,效率更高&#…

分布式并行训练(DP、DDP、DeepSpeed)

[pytorch distributed] 01 nn.DataParallel 数据并行初步 数据并行 vs. 模型并行 数据并行:模型拷贝(per device),数据 split/chunk(对batch切分) 每个device上都拷贝一份完整模型,每个device分…

Android实现二维码扫描功能(一)ZXing插件接入

简介 关于Android扫描二维码的功能实现,网上有很多相关资料。在对比之后,选用了前辈了修改过的ZXing直接接入到项目中,特制作此demo,介绍整个过程。 (最新更新)本篇文章讲解的接入方法对部分开发者新人来说…

Molecular Cancer|CDK9抑制诱导表观遗传重编程,揭示了规避淋巴瘤耐药性的策略

细胞周期蛋白依赖性激酶(CDK)蛋白家族在细胞周期进程(如CDK1/2/4/6)和RNA转录(如CDK7/8/9/11)的调控中起着不可或缺的作用。由于染色体区域易位或基因扩增导致的CDKs表达失调与肿瘤发生有关。在淋巴瘤细胞中…

无线通信——Mesh自组网的多跳性

Mesh的多跳性 Mesh网络具备多跳性。什么是多跳性呢?上面说过,每一个具备Mesh网络的设备都是独立的节点。因此,当我发出一条数据时,这些数据会通过跳跃到达不同的网络节点,数据从一个节点跳到另一个节点,直到…