JVM工作原理与实战(三):字节码文件的组成

专栏导航

JVM工作原理与实战

RabbitMQ入门指南

从零开始了解大数据


目录

专栏导航

前言

一、基础信息

1.Magic魔数

2.主副版本号

3.其他信息

二、常量池

1.案例解析

三、方法

1.方法介绍

2.案例解析

四、字段

五、属性

总结


前言

JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了字节码文件的基础信息、常量池、方法、字段、属性等内容。


一、基础信息

字节码文件的基础信息包括魔数、字节码文件对应的Java版本号、访问标识(public final等等)、父类和接口内容。

1.Magic魔数

文件是无法通过文件扩展名来确定文件类型的,文件扩展名可以随意修改,不影响文件的内容。软件使用文件的头几个字节(文件头)去校验文件的类型,如果软件不支持该种类型就会出错。在Java字节码文件中,将文件头称为magic魔数

文件类型字节数文件头
JPEG (jpg)3FFD8FF
PNG (png)489504E47(文件尾也有要求)
bmp2424D
XML (xml)53C3F786D6C
AVI (avi)441564920
Java字节码文件 (.class)4CAFEBABE

通过NotePad++使用十六进制插件查看class文件:

2.主副版本号

版本号用于标识字节码文件的版本。它包括主版本号和副版本号。主版本号表示编译字节码文件的JDK版本,而副版本号则用于标识不同版本的字节码文件。通过比较字节码文件的主版本号和运行时的JDK版本,可以判断两者是否兼容。

JDK1.0-1.1使用了 45.0-45.3,JDK1.2是46之后每升级一个大版本就加1。1.2之后大版本号计算方法为主版本号 - 44,比如主版本号52就是JDK8。

3.其他信息

访问标识:在Java字节码文件中用于描述类的访问权限和特性。它包括public、private、protected和默认(无标识)等访问级别,以及final、abstract、interface等修饰符。这些标识确定了类的可见性和行为特性,影响着类的使用和继承。

类、父类、接口索引:在字节码文件中,父类和接口的内容通过索引值来表示。这些索引值指向类或接口在常量池中的位置,以便在运行时能够找到它们的相关信息。通过这些索引值,JVM可以在运行时加载并链接所需的类和接口,从而正确执行程序。

二、常量池

常量池是字节码文件中的一个重要组成部分,主要用于存储程序中的常量值,如字符串常量、类或接口名、字段名等。常量池的主要作用是避免相同的内容在字节码文件中重复定义,从而节省空间

在字节码指令中,可以通过常量池中的编号引用相应的常量值。每个常量在常量池中都有一个唯一的编号,编号从1开始。通过这些编号,字节码指令可以快速地定位到常量池中的数据,从而实现高效的数据访问。在字节码指令中引用常量池的过程称为符号引用。通过符号引用来替代实际的数据值,可以在运行时动态地解析和加载相应的数据,提高程序的灵活性和可维护性。

1.案例解析

案例一:

案例代码:

public class ConstantPoolTest {public static final String a1 = "This is a test";public static final String a2 = "This is a test";public static void main(String[] args) {ConstantPoolTest constantPoolTest = new ConstantPoolTest();}
}

查看字段常量值索引(a1和a2),指向cp_info #8:

进入常量池cp info #8,看到字符串文本内容在cp_info #27:

 进入常量池cp_info #27,可以看到字符串文本内容:

在上面的示例中,字符串常量"This is a test"在常量池中只存储一次。在字节码指令中,可以通过常量池中的编号来引用这两个常量。因此,常量池避免了相同内容的重复定义,节省了存储空间。

案例二:

案例代码:

public class ConstantPoolTest2 {public static final String a1 = "abc";public static final String a2 = "abc";public static final String abc = "abc";public static void main(String[] args) {ConstantPoolTest2 constantPoolTest = new ConstantPoolTest2();}
}

查看字段常量值索引,指向cp_info #8:

 进入常量池cp info #8,看到字符串文本内容在cp_info #10:

 进入常量池cp_info #10,可以看到字符串文本内容:

查看字段abc名称所在常量池,指向cp_info #10:

三、方法

1.方法介绍

在JVM字节码文件中,方法部分是核心,它包含了程序执行的具体指令。这些指令是以字节码的形式存在的,是Java源代码的编译结果。

  • 字节码指令:字节码中的方法区域是存放字节码指令的核心位置,字节码指令的内容存放在方法的Code属性中。
  • 操作数栈:操作数栈在字节码指令执行中起到关键的作用。它是一个后进先出(LIFO)的数据结构,用于临时存储数据。几乎所有的字节码指令都会用到操作数栈,无论是从栈顶弹出数据,还是将数据压入栈中。
  • 局部变量表:局部变量表是存放方法中定义的局部变量的位置。每个方法在JVM中都有一个关联的局部变量表,这个表定义了方法的参数和在方法体内部声明的局部变量。局部变量表中的每个条目都包含一个变量的名称、类型和其在方法中的偏移量。这个偏移量表示该变量在方法栈帧中的位置。
  • 局部变量表数组:局部变量表数组是存放这些局部变量表的数组。每一个方法对应一个局部变量表,该表记录了该方法的所有局部变量的信息,包括它们的名称、类型和偏移量等。这些信息对于JVM在运行时解析字节码和执行相应的操作非常重要。

右键查看JVM规范:

 JVM规范:

2.案例解析

案例一:

案例代码:

public class Demo1 {public static void main(String[] args) {int i=0;i = i++;}
}

 查看方法的字节码信息:

 字节码信息解析:

iconst_0将0放入操作数栈
istore_1从操作数栈取出放入局部变量表1号位置
iload_1从局部变量表1号位置加载数据到操作数栈
iinc 1 by 1在局部变量表1号位置增加1
istore_1将操作数栈中的值保存到局部变量表
return方法结束,返回

案例二:

案例代码:

public class Demo2 {public static void main(String[] args) {int i = 0;int j = i + 1;}
}

 查看方法的字节码信息:

  字节码信息解析:

iconst_0将常量0放入操作数栈
istore_1从操作数栈取出放入局部变量表1号位置
iload_1将局部变量表1中的数据放入操作数栈
iconst_1将常量1放入操作数栈
iadd将操作数栈顶部的两个数据进行累加,结果放入栈中
istore_2从操作数栈取出放入局部变量表2号位置
return方法结束,返回

四、字段

在JVM字节码文件中,字段部分包含了当前类或接口声明的字段信息。这些字段包括类的成员变量、静态变量、常量等。字段信息在类的字节码文件中被组织为一个字段表,每个字段在表中都有一个唯一的字段表条目。

五、属性

在JVM字节码文件中,属性部分包含了描述类或接口的各种元数据信息。这些属性提供了关于类或接口的附加信息,用于支持某些JVM特性和工具。

常见的属性:

  • 源码的文件名:这个属性提供了类的源文件名,可以帮助调试和错误跟踪。它允许开发人员在运行时与源代码对应,这对于理解和调试代码非常有用。
  • 内部类的列表:如果一个类包含内部类或嵌套类,那么这个属性将列出所有的内部类和嵌套类。这对于解析和执行嵌套类非常关键。
  • 注解:注解是一种提供元数据的方法,可以用于标记代码中的特定元素。在字节码文件中,注解被表示为属性,提供了关于类、方法、字段等的额外信息。
  • 签名:这个属性提供了关于类、方法或字段的签名信息,包括它们的名称和类型。这对于验证类型和调用方法非常重要。
  • 其他属性:还有其他一些属性,如行号表、本地变量表等,这些属性用于支持调试和其他高级功能。


总结

JVM是Java程序的运行环境,负责字节码解释、内存管理、安全保障、多线程支持、性能监控和跨平台运行。本文主要介绍了字节码文件的基础信息、常量池、方法、字段、属性等内容,希望对大家有所帮助。

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

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

相关文章

【笔试强训】Day1_贪心算法_组队竞赛

题目链接:牛客_组队竞赛 目录 题目解析 代码书写 知识补充 题目解析 题目让我们求所有队伍的水平值总和最大 由题可得: 队伍的水平值等于该队伍队员中第二高水平值; 随机给定3*n个数,需要自己组队并且得出队伍水平最大值; 我…

Python进行批量字符替换的3种方法

一、问题的提出 之前,我写过一篇如何在word中计算数学算式: 如何用Python批量计算Word中的算式-CSDN博客 为了计算算式,就需要对算式进行格式化,把不规则的算式转换成规则的算式,这时就会涉及到一些字符的批量替换。…

山西电力市场日前价格预测【2024-01-03】

日前价格预测 预测说明: 如上图所示,预测明日(2024-01-03)山西电力市场全天平均日前电价为208.80元/MWh。其中,最高日前电价为358.56元/MWh,预计出现在18:00。最低日前电价为0.00元/MWh,预计出…

Windows上ModbusTCP模拟Master与Slave工具的使用

场景 Modbus Slave 与 Modbus Poll主从设备模拟软件与Configure Virtual Serial串口模拟软件使用: Modebus Slave 与 Modbus Poll主从设备模拟软件与Configure Virtual Serial串口模拟软件使用_modbus poll激活-CSDN博客 数据对接协议为Modbus TCP,本地开发需要使…

水果软件2024FL Studio21.3mac苹果中文版

FL STUDIO21发布,提供您一直在等待的出色工作流程功能。通过新效果、多个播放列表曲目选择和无所畏惧的撤消一切编辑,将您的音乐带入2024年。FL Studio21中文完整版是一个功能齐全、开放式架构的PC音乐创作和制作环境。它具有基于音乐音序器的图形用户界…

【番外】在Windows安装Airsim/UE4踩坑合集

在Windows安装Airsim/UE4踩坑合集 1.安装过程中一定要确保Epic Games Launcher是英文环境,保存路径什么的也尽量是英文。2.UE4中的虚幻引擎一定要安装4.27版本以上的,不然的话最后运行vs的时候会报语法错误,网上根本查不到的那种错误。换了版…

Android 13 - Media框架(29)- MediaCodec(四)

上一节我们了解了如何通过 onInputBufferAvailable 和 getInputBuffer 获取到 input buffer index,接下来我们一起学习上层如何拿到buffer并且向下写数据的。 1、获取 input Buffer 获取 MediaCodec 中的 buffer 有两种方式,一种是调用 getInputBuffers…

【ArcGIS微课1000例】0083:地震灾害图件制作之土壤类型分布图

本文基于1:400万矢量土壤图,制作甘肃积石山6.2级地震100km范围内土壤类型分布图。 文章目录 一、土壤分布图预览二、数据集来源及简介三、土壤分布图制作一、土壤分布图预览 二、数据集来源及简介 1. 数据来源 数据集为1:400万中国土壤图,1:400万中国土壤图(2000)由中国科…

BloombergGPT—金融领域大模型

文章目录 背景BloombergGPT数据集金融领域数据集通用数据集分词 模型模型结构模型相关参数训练配置训练过程 模型评估评估任务分布模型对比金融领域评估通用领域评估 背景 GPT-3的发布证明了训练非常大的自回归语言模型(LLM)的强大优势。GPT-3有1750亿个…

工程(十七)——自己数据集跑R2live

博主创建了一个科研互助群Q:772356582,欢迎大家加入讨论。 r2live是比较早的算法,编译过程有很多问题,通过以下两个博客可以解决 编译R2LIVE问题&解决方法-CSDN博客 r2live process has died 问题解决了_required process …

3Dmax模型打开后灯光全没了---模大狮模型网

在3ds Max中,有时您可能会打开一个3dmax模型文件后发现灯光似乎丢失了。这可能是由于以下原因之一导致的: 灯光层被隐藏或删除了。在3ds Max中,您可以将不同的对象分配给不同的层,以方便管理和编辑。如果灯光对象被分配到另一个层…

【数学建模美赛M奖速成系列】Matplotlib绘图技巧(二)

Matplotlib绘图技巧(二) 写在前面2. 函数间区域填充函数fill_between()和fill()参数: 3. 散点图 scatter4. 直方图 hist5. 条形图 bar5.1 一个数据样本的条形图参数: 5.2 多个数据样本进行对比的直方图5.3 水平条形图参数 5.4 绘制…

堆排序(C语言版)

一.堆排序 堆排序即利用堆的思想来进行排序,总共分为两个步骤: 1. 建堆 升序:建大堆 降序:建小堆 2. 利用堆删除思想来进行排序 1.1.利用上下调整法实现堆排序 第一步:建堆 好了,每次建堆都要问自己…

ArkTS基本概念装饰器

目录 ArkTS基本概念 装饰器汇总 ArkTS基本概念 ArkTS是HarmonyOS的主力应用开发语言。 它在TypeScript(简称TS)的基础上,匹配ArkUI框架,扩展了声明式UI、状态管理等相应的能力,让开发者以更简洁、更自然的方式开发跨…

cocos creator + vscode debug

安装插件 安装插件:JavaScript Debugger 配置 7456 为本地cocos creator的启动端口 启动debug调试 选择对应的启动方式

低成本TB级数据库技术选型之思考两三点

一、背景 前段时间在搞毕业论文的选题,最头疼的就是大量的文献检索和阅读,从研究的角度上我们可以将文献分为四类: 理论文献:为研究提供理论的框架和基础的文献。这些文献可能并不会和所做的研究直接相关,甚至由于理…

叫板GPT-4的Gemini,我做了一个聊天网页,可图片输入,附教程

先看效果: 简介 Gemini 是谷歌研发的最新一代大语言模型,目前有三个版本,被称为中杯、大杯、超大杯,Gemini Ultra 号称可与GPT-4一较高低: Gemini Nano(预览访问) 为设备端体验而构建的最高效模型,支持离线使用场景。…

基于PI控制的PMSM永磁同步电机控制系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 PMSM数学模型 4.2 矢量控制策略 4.3 PI控制器设计 4.4 控制系统实现 5.完整工程文件 1.课题概述 基于PI控制的PMSM永磁同步电机控制系统simulink建模与仿真。其中,基于PI(…

查看ios app运行日志

摘要 本文介绍了一款名为克魔助手的iOS应用日志查看工具,该工具可以方便地查看iPhone设备上应用和系统运行时的实时日志和奔溃日志。同时还提供了奔溃日志分析查看模块,可以对苹果奔溃日志进行符号化、格式化和分析,极大地简化了开发者的调试…

极值和平均值-第11届蓝桥杯选拔赛Python真题精选

[导读]:超平老师的Scratch蓝桥杯真题解读系列在推出之后,受到了广大老师和家长的好评,非常感谢各位的认可和厚爱。作为回馈,超平老师计划推出《Python蓝桥杯真题解析100讲》,这是解读系列的第22讲。 极值和平均值&…