类加载过程Java虚拟机(JVM)详细

类加载过程是Java虚拟机(JVM)将类的字节码文件加载到内存中,并生成对应的类对象的过程。这个过程主要包括加载、验证、准备、解析和初始化五个阶段,每个阶段都有其特定的任务和作用。以下是对每个阶段的详细解释:

1. 加载(Loading)

加载阶段是类加载过程的第一个阶段。在这个阶段,JVM的主要任务是将类的字节码从各种来源(如本地文件系统、网络、数据库等)转化为二进制字节流,并将其加载到内存中。同时,JVM会为这个类在方法区创建一个对应的Class对象,这个Class对象将成为这个类在JVM中的唯一标识,也是对这个类进行各种操作的入口。

需要注意的是,加载阶段只是将类的字节码加载到内存中,并没有进行任何形式的校验或初始化。此外,JVM并没有规定类的字节流必须从.class文件中加载,程序员可以通过自定义的类加载器来指定加载的来源。

2. 验证(Verification)

验证阶段是类加载过程的第二个阶段。在这个阶段,JVM会对加载到内存中的字节码进行校验,以确保其符合JVM规范,并且没有安全问题。验证阶段主要包括以下四个方面的校验:

  • 文件格式验证:确保字节流符合Class文件格式规范,如是否以魔数0xCAFEBABE开头、主次版本号是否在当前虚拟机处理范围内等。
  • 元数据验证:对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言规范的要求。例如,检查类是否有父类、是否实现了父类的抽象方法、是否重写了父类的final方法等。
  • 字节码验证:通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的。例如,检查操作数栈的数据类型与指令代码序列是否能配合工作、保证方法中的类型转换有效等。
  • 符号引用验证:确保解析后的直接引用是合法的。例如,通过符号引用能找到对应的类和方法、符号引用中类、属性、方法的访问性是否能被当前类访问等。

验证阶段虽然对于程序的运行期没有影响,但它是JVM对自身保护的一项重要工作。如果所引用的类经过反复验证,那么可以考虑采用-Xverify:none参数来关闭大部分的类验证措施,以缩短虚拟机类加载的时间。

3. 准备(Preparation)

准备阶段是类加载过程的第三个阶段。在这个阶段,JVM会为类的静态变量分配内存,并为其设置初始值。这些初始值通常是数据类型的零值(如int类型的初始值为0、long类型的初始值为0L、引用类型的初始值为null等),而不是用户定义的初始值。

需要注意的是,准备阶段只会为静态变量分配内存并初始化零值,而不会为实例变量分配内存或初始化。实例变量的内存分配和初始化将在对象的实例化阶段进行。此外,对于被static final修饰的常量,在准备阶段就会被赋予用户希望的值(即编译时常量),而不是零值。

4. 解析(Resolution)

解析阶段是类加载过程的第四个阶段。在这个阶段,JVM会将常量池内的符号引用替换为直接引用。符号引用是一种定义,可以是任何字面上的含义,如类和接口的全限定名、字段的名称和描述符、方法的名称和描述符等。而直接引用则是直接指向目标的指针、相对偏移量或是一个能间接定位到目标的句柄。

解析阶段的主要任务是将类、接口、字段和方法的符号引用转换为直接引用,以便在程序运行时能够直接访问到目标对象或方法。这个过程可以看作是当前加载的这个类和它所引用的类正式进行“连接”的过程。

需要注意的是,解析阶段不一定在初始化阶段之前进行。在某些情况下,如Java语言的运行时绑定(也称为动态绑定)中,解析阶段可能会在初始化阶段之后进行。

5. 初始化(Initialization)

初始化阶段是类加载过程的最后一个阶段。在这个阶段,JVM会真正开始执行类中编写的Java程序代码,即执行类的构造器()方法。这个方法是由Javac编译器自动生成的,用于执行类中所有静态变量的赋值动作和静态语句块(static{}块)中的语句。

()方法与类的构造函数(即在虚拟机视角中的实例构造器()方法)不同。它不需要显式地调用父类构造器,Java虚拟机会保证在子类的()方法执行前,父类的()方法已经执行完毕。此外,()方法对于类或接口来说并不是必需的。如果一个类中没有静态语句块,也没有对变量的赋值操作,那么编译器可以不为这个类生成()方法。

在初始化阶段,除了执行()方法外,JVM还会为类的实例变量分配内存并初始化(如果实例变量在声明时指定了初始值或在构造器中进行了初始化)。同时,类的实例化也会在这个阶段进行。

综上所述,类加载过程是Java虚拟机将类的字节码文件加载到内存中并生成对应的类对象的过程。这个过程包括加载、验证、准备、解析和初始化五个阶段,每个阶段都有其特定的任务和作用。了解这些阶段有助于我们更好地理解Java程序的运行原理和解决类加载过程中可能遇到的问题。

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

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

相关文章

基于灰色神经网络的订单需求预测

灰色神经网络(Grey Neural Network, GNN) 是将灰色系统理论与人工神经网络相结合的一种模型,旨在处理不完全信息和小样本问题。灰色神经网络利用灰色系统的预测优势和神经网络的学习能力,能够在信息不完整或数据不充分的情况下实现…

nerdctl:与 Docker 兼容的 containerd CLI

nerdctl 是一个用于容器管理的命令行工具,它旨在提供与 Docker CLI 相似的用户体验,但却是为 containerd 这样的低级容器运行时设计的。containerd 是一个行业标准的容器运行时,被广泛用作 Kubernetes 等容器编排平台的一部分。nerdctl 通过简…

java基础教程第16篇( 正则表达式)

Java 正则表达式 正则表达式定义了字符串的模式。 正则表达式可以用来搜索、编辑或处理文本。 正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。 Java 提供了 java.util.regex 包,它包含了 Pattern 和 Matcher 类,用于处理正…

百问FB显示开发图像处理 - 图像调整

2.4 图像调整 2.4.1 图像的缩放 2.4.1.1 图像缩放算法浅析 图像缩放算法有很多种,这里参考网友"lantianyu520"所著的"图像缩放算法"。 原理浅析 ​ 要理解这个图像缩放算法的原理,最重要的是需要理解:对于图像上的每…

部署项目报错

vue2项目部署后 Error: Cannot find module /views/*** 1.起因 登录页、首页等静态页面可以正常进入,后端访问也正常,可以获取到验证码。 但是登录之后会发现首页空白或者进入不到首页 F12查看有报错信息:Error: Cannot find module ‘/v…

怎麼解決路由器IP地址衝突?

路由器IP地址衝突通常發生在網路中有兩個設備嘗試使用相同的IP地址時。這種衝突會導致網路連接問題,因為每個設備需要一個唯一的IP地址才能正常通信。 1. 重啟設備 重啟路由器和設備:有時候簡單的重啟可以解決問題,設備重新獲取一個新的IP地…

c# Grpc取消

net6.0 通过CancellationTokenSource 客户端取消Grpc,服务端判断 IsCancellationRequested 是否取消。 proto: syntax "proto3";// 引用可空类型 import "google/protobuf/wrappers.proto";option csharp_namespace "Grpc.Common"…

opencv复习

目录 1.core 1.图像变换 1.1 affine仿射变换 1.2 透视变换 2.四元数(旋转) 2.1 轴角转四元数 2.2 旋转矩阵转四元数 2.3 欧拉角转旋转矩阵 2.4 四元数转旋转矩阵 2.5 四元数用eigen用的比较多 2. imgproc. Image Processing 2.1 bilateralF…

10-高级主题

第10节 高级主题 在这一节中,我们将探讨一些 Python 中的高级主题,包括装饰器、生成器、上下文管理器、元类以及常用的设计模式。这些高级特性能够帮助你编写更强大、更灵活的代码。 10.1 装饰器 装饰器是一种特殊类型的函数,可以修改其他函数…

蓝桥杯分治

P1226 【模板】快速幂 题目描述 给你三个整数 𝑎,𝑏,𝑝a,b,p,求 𝑎𝑏 mod 𝑝abmodp。 输入格式 输入只有一行三个整数,分别代表 𝑎,𝑏,𝑝a,b,p。…

【webApp之h5端实战】首页评分组件的原生实现

关于评分组件,我们经常在现代前端框架中用到,UI美观效果丰富,使用体验是非常不错的。现在自己动手使用原生js封装下评分组件,可以用在自己的项目中。 组件实现原理 点击的❤左侧包括自己都是高亮的样式,右侧都是灰色的样式,这样就能把组件的状态区分开了。右边再加上辅…

C++小碗菜之二:软件单元测试

“没有测试的代码重构不能称之为重构,它仅仅是垃圾代码的到处移动” ——Corey Haines 目录 前言 什么是单元测试? 单元测试的组成 单元测试的命名 单元测试的独立性 Google Test 单元测试的环境配置与使用 1. Ubuntu下安装 Google Test 2. 编写…

ssm 多数据源 注解版本

application.xml 配置如下 <!-- 使用 DruidDataSource 数据源 --><bean id"primaryDataSource" class"com.alibaba.druid.pool.DruidDataSource" init-method"init" destroy-method"close"></bean> <!-- 使用 数…

【C++】格式化输出详解:掌握 cout 的进阶用法

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;格式化输出的理论概述&#x1f4af;控制输出宽度和填充字符setw 操作符setfill 操作符 &#x1f4af;控制浮点数的显示格式fixed 与 scientificsetprecision &#x1f4af;…

uC/OSII学习笔记(一)任务的增删改查

使用天玛智控的控制器&#xff0c;基础工程文件已移植ucosii。 正常的任务创建流程为&#xff1a; 1.OSInit()&#xff1b; 2.OSTaskCreate()&#xff1b; 3.OSStart()&#xff1b; 但是天玛对其有做修改&#xff0c;任务创建直接调用OSTaskCreate()函数即可&#xff0c;不用在…

【日常记录-Mybatis】PageHelper导致语句截断

1. 简介 PageHelper是Mybatis-Plus中的一个插件&#xff0c;主要用于实现数据库的分页查询功能。其核心原理是将传入的页码和条数赋值给一个Page对象&#xff0c;并保存到本地线程ThreadLocal中&#xff0c;接下来&#xff0c;PageHelper会进入Mybatis的拦截器环节&#xff0c;…

Linux入门攻坚——40、Linux集群系统入门-lvs(1)

Cluster&#xff0c;集群&#xff0c;为了解决某个特定问题将多台计算机组合起来形成的单个系统。 这个单个集群系统可以扩展&#xff0c;系统扩展的方式&#xff1a;scale up&#xff0c;向上扩展&#xff0c;更换更好的主机&#xff1b;scale out&#xff0c;向外扩展&…

Canal 深入解析:从原理到实践的全面解读

Canal 深入解析&#xff1a;从原理到实践的全面解读 官网&#xff1a;https://github.com/alibaba/canal Canal 是阿里巴巴开源的一款分布式增量数据同步工具&#xff0c;广泛应用于数据同步、实时数据处理和数据库的增量备份等场景。它可以通过监听 MySQL 数据库的 binlog&am…

Java中的数据存储结构解析与应用

一、引言 在Java编程中&#xff0c;数据存储结构是程序设计的基础。合理选择和使用数据结构可以提高程序的性能和可维护性。本文将带您了解Java中的各种数据存储结构&#xff0c;并探讨其优缺点及适用场景。 二、基本数据类型 Java提供了8种基本数据类型&#xff0c;分别是b…

Home Assistant智能家居盒子用了一段时间发现没有存储空间了,怎么清理释放?

环境&#xff1a; Unbuntu 20.04 Home Assistant 2023.8.0 问题描述&#xff1a; Home Assistant智能家居盒子用了一段时间发现没有存储空间了&#xff0c;怎么清理释放&#xff1f; 解决方案&#xff1a; 1.查看HA日志文件&#xff0c;有比较大&#xff0c;直接删了 2.查…