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

JVM工作原理与实战(六):类的生命周期-连接阶段

专栏导航

JVM工作原理与实战

RabbitMQ入门指南

从零开始了解大数据


目录

专栏导航

前言

一、类的生命周期

1.加载(Loading)

2.连接(Linking)

3.初始化(Initialization)

4.使用(Using)

5.卸载(Unloading)

二、连接阶段

1.验证

2.准备

3.解析

总结


前言

JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了类的生命周期、类的连接阶段等内容。


一、类的生命周期

类的生命周期描述了一个类加载、连接、初始化、使用、卸载的整个过程。

1.加载(Loading)

加载阶段是类的生命周期的起始点。当应用程序首次需要使用某个类时,Java虚拟机(JVM)会负责加载这个类。加载是通过类的加载器(ClassLoader)完成的,它会查找并加载类的二进制数据。这个过程包括将类的字节码从文件系统、JAR文件或网络加载到内存中。

2.连接(Linking)

连接阶段是加载阶段的后续,它包括验证、准备和解析三个子阶段。

  • 验证(Verification):验证阶段主要是确保被加载的类文件数据符合JVM规范,没有安全方面的隐患,以及是否与应用程序的其它部分兼容。验证过程包括文件格式验证、元数据验证、字节码验证和符号引用验证。
  • 准备(Preparation):准备阶段是为类的静态变量分配内存,并设置默认的初始值。需要注意的是,准备阶段并不会执行任何初始化操作。
  • 解析(Resolution):解析阶段是将符号引用转换为直接引用。在Java中,符号引用是一个类的全限定名,而直接引用是一个直接指向内存中的地址的指针。解析阶段发生在运行时,而不是编译时。

3.初始化(Initialization)

初始化阶段是类加载过程中的最后一步,当准备和解析阶段完成后,JVM会执行类的构造器方法,这个方法是由编译器自动收集类中的所有类变量的赋值动作和静态代码块集合来的。需要注意的是,构造器方法中的代码只在类被首次使用时执行一次。

4.使用(Using)

一旦类被成功加载、连接并初始化后,就可以被实例化并用于执行应用程序的业务逻辑。在应用程序运行期间,类可能会被频繁地使用。

5.卸载(Unloading)

当应用程序不再需要某个类时,该类的实例以及与其相关的资源将会被回收,这个过程就是卸载。但是需要注意的是,只有当一个类不再被任何活动对象所引用时,它才会被卸载。另外,JVM的垃圾回收机制(Garbage Collection, GC)负责自动处理类的卸载和资源的回收。

二、连接阶段

1.验证

在Java类的生命周期中,连接阶段是一个至关重要的环节,它确保了Java字节码文件在被Java虚拟机(JVM)加载前满足一定的规范和要求。连接阶段的首要任务是验证,这一过程对Java字节码文件进行了严格的检查,以确保其遵守《Java虚拟机规范》中定义的各种约束。这一验证过程通常对程序员是透明的,不需要他们直接参与。

验证过程主要包括以下四个部分:

  • 文件格式验证:这是验证的第一步,主要检查字节码文件的基本格式。例如,它会验证文件是否以特定的魔数(magic number)0xCAFEBABE开头,这是Java类文件的标识。此外,还会检查文件的主次版本号是否与当前Java虚拟机的版本兼容。版本号的检查是确保类文件是用与当前JVM兼容的Java编译器编译的。

  • 元数据验证:在这一步中,验证器会检查类的元数据信息。这包括类的继承关系、接口实现、字段和方法的存在性和访问权限等。例如,验证器会确保每个类都有父类(除了java.lang.Object),并且类的继承层次结构没有出现问题。此外,还会检查方法的字节码,确保它们不会执行非法的操作,如跳转到不正确的位置。

  • 字节码验证:这是最复杂的一步,验证器会深入分析方法的字节码,确保它们符合Java虚拟机的语义规则。这个过程会检查诸如类型安全、操作数栈的数据流和使用情况等。字节码验证的目的是防止潜在的恶意代码或由于编译器错误导致的无效代码被执行。
  • 符号引用验证:在这一步中,验证器会检查类文件中的符号引用。符号引用是类在编译时对其他类、方法或字段的引用,这些引用在类加载时会被解析为实际的内存地址。验证器会确保这些符号引用是有效的,例如,不会访问其他类的私有方法或不存在的字段。

在Hotspot JDK 8的虚拟机源码中,版本号的检测是通过一段特定的代码来实现的。这段代码确保了主版本号(major version)和副版本号(minor version)都在Java虚拟机支持的范围内。具体来说,主版本号不能高于运行环境的主版本号,如果主版本号相等,则副版本号也不能超过运行环境所支持的最大副版本号。这样的版本号检测机制确保了类文件与运行环境的兼容性。

Hotspot JDK8中虚拟机源码对版本号检测的代码如下:

return (major >= JAVA_MIN_SUPPORTED_VERSION) && (major <= max_version) && ((major != max_version) || (minor <= JAVA_MAX_SUPPORTED_MINOR_VERSION));
major >= JAVA_MIN_SUPPORTED_VERSIONmajor(主版本号)大于或等于最小支持的Java版本
major <= max_versionmajor(主版本号)小于或等于最大支持的Java版本

(major != max_version) ||

(minor <= JAVA_MAX_SUPPORTED_MINOR_VERSION)

major(主版本号)不是最大支持版本,或者minor(次版本号)在最大支持范围内

验证阶段是Java类加载过程中非常重要的一环,它确保了只有符合规范的类文件才能被Java虚拟机加载和执行。这一过程不仅增强了Java平台的安全性,还提高了代码的健壮性和可移植性。

2.准备

准备阶段的主要任务是为类的静态变量分配内存,并设置这些变量的初始值。准备阶段只会为静态变量赋予初始值,而不是最终的值。每一种基本数据类型和引用数据类型在准备阶段都有其特定的初始值。

以下是基本数据类型和引用数据类型的初始值列表:

数据类型初始值
int0
long0L
short0
char‘\u0000’
byte0
booleanfalse
double0.0
引用数据类型null

这些初始值是Java虚拟机规范所规定的,它们在准备阶段被自动赋予给相应的静态变量。

然而,有一个特殊的情况需要注意,那就是被final修饰的基本数据类型的静态变量。在准备阶段,如果静态变量被final修饰,并且其值在编译时就已经确定,那么Java虚拟机将直接将该值赋给静态变量,而不是赋予初始值。这一特性使得被final修饰的静态变量在准备阶段就能获得其最终的值。

下面通过两个示例来说明这一点:

示例一(类Test包含一个普通的静态变量i):

public class Test {public static int i = 1;public static void main(String[] args) {}
}

对于这个示例,在准备阶段,静态变量i会被赋予其初始值0,而不是最终值1,最终值1的赋值发生在初始化阶段。

示例二(类Test包含一个被final修饰的静态变量i):

public class Test {public static final int i = 1;public static void main(String[] args) {}
}

对于这个示例,在准备阶段,静态变量i会被直接赋予其最终值1,因为它是一个编译时常量。这意味着在准备阶段完成后,静态变量i就已经获得了其最终的值,而不需要等到初始化阶段。

在Java类的生命周期的连接阶段中,准备阶段是一个关键步骤,它负责为静态变量分配内存并设置初始值。对于被final修饰的静态变量,如果其值在编译时就已经确定,那么准备阶段将直接赋予其最终值。这一特性为Java程序员提供了一种优化静态变量初始化的手段。

3.解析

解析阶段作为连接阶段的一部分,其主要任务是将常量池中的符号引用转换为直接引用

符号引用:

在Java字节码中,常量池用于存储各种常量,如字符串、类名等。这些常量在常量池中通过编号进行索引。在字节码文件中,这些索引被用作符号引用。例如,当我们在字节码中引用一个类时,实际上是通过一个在常量池中的索引来引用该类,这个索引被称为类符号引用。同样地,字段和方法的引用也是通过相应的符号引用来表示的。

直接引用:

与符号引用不同,直接引用是直接指向目标对象的指针或地址。这意味着直接引用是具体的、指向内存中的某个位置的地址。通过直接引用,JVM可以直接定位并访问目标对象,而不必通过一系列的索引和查找操作。

解析过程:

在解析阶段,JVM将常量池中的符号引用转换为直接引用,这一过程是由JVM自动完成的。JVM在解析阶段会遍历字节码中的指令,将遇到的符号引用替换为直接引用。这个过程涉及到在运行时解析符号引用,并获取目标对象的实际内存地址。

举个例子,如果字节码中有一个对某个类的字段的访问指令,那么在解析阶段,JVM会找到该字段的实际内存地址,并将该地址作为直接引用存储在相应的指令中。这样,当执行该指令时,JVM可以直接访问该字段,而不需要通过查找常量池来获取符号引用。

解析阶段是连接阶段中的关键环节之一,它确保了JVM能够高效地访问和操作目标对象。通过将符号引用转换为直接引用,JVM能够提高指令执行的速度并降低内存开销。这也是Java虚拟机实现高效运行的重要手段之一。


总结

JVM是Java程序的运行环境,负责字节码解释、内存管理、安全保障、多线程支持、性能监控和跨平台运行。本文主要介绍了类的生命周期、类的连接阶段等内容,希望对大家有所帮助。

相关文章:

JVM工作原理与实战(六):类的生命周期-连接阶段

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、类的生命周期 1.加载&#xff08;Loading&#xff09; 2.连接&#xff08;Linking&#xff09; 3.初始化&#xff08;Initialization&#xff09; 4.使用&#xff08;Using&…...

【OCR】 - Tesseract OCR在Windows系统中安装

Tesseract OCR 在Windows环境下安装Tesseract OCR&#xff08;Optical Character Recognition&#xff09;通常包括以下几个步骤&#xff1a; 下载Tesseract 访问Tesseract的GitHub发布页面&#xff1a;https://github.com/tesseract-ocr/tesseract/releases找到适合你操作系…...

YOLOv8改进 | 损失函数篇 | SlideLoss、FocalLoss分类损失函数助力细节涨点(全网最全)

一、本文介绍 本文给大家带来的是分类损失 SlideLoss、VFLoss、FocalLoss损失函数,我们之前看那的那些IoU都是边界框回归损失,和本文的修改内容并不冲突,所以大家可以知道损失函数分为两种一种是分类损失另一种是边界框回归损失,上一篇文章里面我们总结了过去百分之九十的…...

计算机网络试题——填空题(附答案)

在OSI模型中&#xff0c;第一层是____________层。 答案&#xff1a;物理&#xff08;Physical&#xff09; TCP协议是一种_____________连接的协议。 答案&#xff1a;面向连接&#xff08;Connection-oriented&#xff09; IPv6地址的位数是____________。 答案&#xff1a;1…...

第二证券:股票私募仓位指数创近八周新高

1月8日&#xff0c;A股几大首要指数全线收跌&#xff0c;上证指数收于日内最低点2887.54点&#xff0c;间隔上一年5月份的阶段高点3418.95点现已跌去了15.54%。 不过&#xff0c;虽然商场仍未清晰止跌&#xff0c;私募基金们却现已进场“抄底”。私募排排网最新发布的私募仓位…...

35-javascript基础,引入方式;变量命名规范

html分为三部分&#xff1b;结构html&#xff0c;表现css&#xff0c;行为js&#xff1b;js就是javascript js包含三部分&#xff1a; ECMAScript&#xff1a;简称ES&#xff0c;ES5&#xff0c;ES6核心语法 DOM&#xff1a;获取和操作html元素的标准方法&#xff1b;BOM&am…...

笔试案例2

文章目录 1、笔试案例22、思维导图 1、笔试案例2 09&#xff09;查询学过「张三」老师授课的同学的信息 selects.*,c.cname,t.tname,sc.score from t_mysql_teacher t, t_mysql_course c, t_mysql_student s, t_mysql_score sc where t.tidc.cid and c.cidsc.cid and sc.sids…...

【嵌入式-网络编程】vmware中使用UDP广播失败问题

问题描述&#xff1a; 自己在vmware中搭建了2台虚拟机&#xff0c;虚拟机A向虚拟机A和虚拟机B发送广播信息&#xff0c;接收端在虚拟机A和虚拟机B&#xff0c;这个时候&#xff0c;由于没配置sin.sin_addr.s_addr htonl(INADDR_ANY);&#xff0c;而是配置的inet_pton(AF_INET,…...

2020年认证杯SPSSPRO杯数学建模D题(第二阶段)让电脑桌面飞起来全过程文档及程序

2020年认证杯SPSSPRO杯数学建模 D题 让电脑桌面飞起来 原题再现&#xff1a; 对于一些必须每天使用电脑工作的白领来说&#xff0c;电脑桌面有着非常特殊的意义&#xff0c;通常一些频繁使用或者比较重要的图标会一直保留在桌面上&#xff0c;但是随着时间的推移&#xff0c;…...

vue3 修饰符大全(近万字长文)

系列文章目录 TypeScript 从入门到进阶专栏 文章目录 系列文章目录前言一、事件修饰符&#xff08;Event Modifiers&#xff09;1、.stop&#xff08;阻止事件冒泡&#xff09;2、.prevent&#xff08;阻止事件的默认行为&#xff09;3、.capture&#xff08;使用事件捕获模式…...

HarmonyOS@State装饰器:组件内状态

State装饰器&#xff1a;组件内状态 State装饰的变量&#xff0c;或称为状态变量&#xff0c;一旦变量拥有了状态属性&#xff0c;就和自定义组件的渲染绑定起来。当状态改变时&#xff0c;UI会发生对应的渲染改变。 在状态变量相关装饰器中&#xff0c;State是最基础的&…...

如何让GPT支持中文

上一篇已经讲解了如何构建自己的私人GPT&#xff0c;这一篇主要讲如何让GPT支持中文。 privateGPT 本地部署目前只支持基于llama.cpp 的 gguf格式模型&#xff0c;GGUF 是 llama.cpp 团队于 2023 年 8 月 21 日推出的一种新格式。它是 GGML 的替代品&#xff0c;llama.cpp 不再…...

使用开源通义千问模型(Qwen)搭建自己的大模型服务

目标 1、使用开源的大模型服务搭建属于自己的模型服务&#xff1b; 2、调优自己的大模型&#xff1b; 选型 采用通义千问模型&#xff0c;https://github.com/QwenLM/Qwen 步骤 1、下载模型文件 开源模型库&#xff1a;https://www.modelscope.cn/models mkdir -p /data/…...

Java工程师面试题解析与深度探讨

Java工程师面试题解析与深度探讨 第一部分&#xff1a;引言 Java作为一门广泛应用的编程语言&#xff0c;拥有庞大的生态系统&#xff0c;Java工程师因此成为众多企业追逐的目标。而在Java工程师的招聘中&#xff0c;面试是了解候选人技能和经验的核心环节。本文将深入探讨一…...

Linux下安装JET2

0. 说明&#xff1a; JET2是一个基于Joint Evolutionary Trees的利用序列和结构信息预测蛋白质界面的软件&#xff0c;详情见: http://www.lcqb.upmc.fr/JET2/JET2.html&#xff0c;http://www.lgm.upmc.fr/JET/JET.html 和 https://doi.org/10.1371/journal.pcbi.1004580 本…...

【PostgreSQL】表管理-表继承

PostgreSQL 表继承 PostgreSQL 实现了表继承&#xff0c;这对于数据库设计人员来说是一个有用的工具。&#xff08;SQL&#xff1a;1999 及更高版本定义了类型继承功能&#xff0c;该功能在许多方面与此处描述的功能不同。 让我们从一个例子开始&#xff1a;假设我们正在尝试…...

Dijkstra算法——邻接矩阵实现+路径记录

本文是在下面这篇文章的基础上做了一些补充&#xff0c;增加了路径记录的功能。具体Dijkstra的实现过程可以参考下面的这篇文章。 [jarvan&#xff1a;Dijkstra算法详解 通俗易懂](Dijkstra算法详解 通俗易懂 - jarvan的文章 - 知乎 https://zhuanlan.zhihu.com/p/338414118) …...

Vim基础操作

参考B站UP&#xff1a;正月点灯笼 vim入门教程&#xff08;共3讲&#xff09; 以下总结&#xff0c;部分搬运自评论区&#xff0c;楼主&#xff1a;-不是飞鱼QAQ&#xff0c;修改部分内容。 vim分为 命令 和 编辑 模式 i进入编辑模式&#xff08; - - INSERT - - &#xff09;…...

Mac上安装 Node.js 的版本管理工具 n,以及 n 使用,的使用

安装 最近刚更换 Mac 本进行项目的开发&#xff0c;刚上手 Mac 本还不是很熟练&#xff0c;需要安装 Node.js 的包管理工具 在 Windows 上我是实用的 nvm 来管理的 Node 版本&#xff0c;但是我尝试下载 Nvm &#xff0c;发现下载安装后的 Nvm 无法使用&#xff0c;提示 “Th…...

Node.js和npm

目录 01_Node.js01.什么是 Node.js目标讲解小结 02.fs模块-读写文件目标讲解小结 03.path模块-路径处理目标讲解小结 04.案例-压缩前端html目标讲解小结 05.认识URL中的端口号目标讲解小结 06.http模块-创建Web服务目标讲解小结 07.案例-浏览时钟目标讲解小结 02_Node.js模块化…...

开源秘密管理工具 phantom-secrets:本地化安全存储与自动化集成指南

1. 项目概述&#xff1a;一个用于秘密管理的开源工具 在软件开发和运维的日常工作中&#xff0c;秘密&#xff08;Secrets&#xff09;的管理一直是个既基础又棘手的问题。无论是数据库密码、API密钥、云服务凭证&#xff0c;还是TLS证书的私钥&#xff0c;这些敏感信息一旦泄露…...

DevOps与MCP协议:构建AI增强型智能运维工作台

1. 项目概述&#xff1a;DevOps与MCP的交汇点最近在GitHub上看到一个挺有意思的项目&#xff0c;叫rohitg00/awesome-devops-mcp-servers。如果你是做DevOps或者对AI辅助编程感兴趣&#xff0c;这个仓库绝对值得你花时间研究。简单来说&#xff0c;这是一个精心整理的列表&…...

3403开源:黄大年茶思屋榜文保姆级全落地解法「34期 3题」融合算力跨层语义感知协同调度体系双路径工程落地全解

华夏之光永存・开源:黄大年茶思屋榜文保姆级全落地解法「34期 3题」 小标题:融合算力跨层语义感知协同调度体系双路径工程落地全解 一、摘要 融合算力跨层语义感知协同调度领域,当下异构算力分立管控、静态资源划分、单任务独占调度等传统模式已触及全球工程性能绝对天花…...

【大模型服务治理实战指南】:奇点智能大会首发的7大避坑法则与3套可落地架构模板

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;大模型服务治理&#xff1a;奇点智能大会 在2024年奇点智能大会上&#xff0c;大模型服务治理成为核心议题。随着LLM推理服务规模化部署&#xff0c;企业面临模型版本混乱、流量调度失衡、资源隔离缺失…...

OpenClaw Mattermost插件:为团队协作平台注入AI智能的轻量集成方案

1. 项目概述&#xff1a;为团队协作平台注入AI灵魂如果你所在的技术团队正在使用 Mattermost 这类自托管、注重数据隐私的团队协作工具&#xff0c;同时又希望引入一个能处理工单、回答疑问、甚至自动执行任务的智能助手&#xff0c;那么你很可能已经厌倦了那些需要复杂 API 调…...

别再傻傻分不清!舵机、步进、无刷、永磁同步,这四种电机到底怎么选?

电机选型实战指南&#xff1a;舵机、步进、无刷与永磁同步的黄金法则 在机器人关节调试现场&#xff0c;一位工程师盯着反复抖动的机械臂摇头&#xff1a;"早知道该用无刷电机..."&#xff1b;创客空间里&#xff0c;几个学生围着一台失控的3D打印机争论&#xff1a…...

SMBus协议深度解析:从基础时序到高级应用

1. SMBus协议基础&#xff1a;从I2C到系统管理总线 第一次接触SMBus时&#xff0c;我误以为它只是I2C的"马甲"。实际调试智能电池项目后才发现&#xff0c;这个1996年由Intel提出的二线制串行总线&#xff0c;在系统管理领域有着独特的价值。简单来说&#xff0c;SMB…...

IDEA进阶指南:巧用Changelist实现多任务并行开发

1. 为什么你需要Changelist功能 作为一个长期使用IDEA进行开发的程序员&#xff0c;我深刻理解多任务并行开发时的痛苦。想象一下这样的场景&#xff1a;你正在开发一个新功能&#xff0c;突然产品经理跑过来说有个紧急bug需要立即修复。这时候你会怎么做&#xff1f;传统做法可…...

机器学习在非洲传染病预测与监测中的实战应用

1. 项目概述&#xff1a;当AI遇见非洲传染病防控在公共卫生领域&#xff0c;时间就是生命&#xff0c;资源就是防线。对于非洲大陆而言&#xff0c;这句话的分量尤为沉重。这里常年承受着全球最沉重的传染病负担&#xff0c;从水源性传播的霍乱、致命性极高的埃博拉&#xff0c…...

Codex Chrome 插件来了|但国内用户安装失败、连接不上、怎么用。这一篇全部搞定

今天早上更新了下Codex最新版本&#xff0c;发现有一个控制Chrome的选项&#xff0c;尝鲜一下&#xff0c;这是什么功能。但是当你真正去下载的时候发现根本不可用&#xff0c;因为暂时对国内用户还没有开发&#xff0c;你会看到下面这个页面。上网查了下&#xff0c;目前还没有…...