深入源码:解析SpotBugs (6)jvm 字节码简介

文章目录

    • 一、JVM字节码概述
      • 一、文件结构概述
      • 二、详细解析
        • 1. 魔数和Class文件的版本
        • 2. 常量池
        • 3. 访问标志
        • 4. 类索引、父类索引与接口索引集合
        • 5. 字段表和方法表
        • 6. 属性表
    • 字节码
    • Spotbugs

作为一名资深的Java开发工程师,对JVM及其字节码有着深入的理解。现在,我将为初级Java开发工程师详细介绍JVM的字节码。

一、JVM字节码概述

Java字节码(Java Bytecode)是Java虚拟机(JVM)执行的一种指令格式。它是Java源代码经过Java编译器(javac)编译后生成的中间代码,存储在.class文件中。这种中间代码不依赖于任何具体的硬件或操作系统,而是由JVM进行解释执行或即时编译(JIT编译)成机器码后执行,从而实现“一次编写,到处运行”的跨平台特性。

一、文件结构概述

Class文件是一组以8位字节为基础单位的二进制流,其中包含了Java虚拟机(JVM)执行程序所需的各种信息。Class文件结构紧凑,数据项目之间严格按照顺序排列,中间没有空隙。这些数据项目通过无符号数和表来存储,主要包括以下几个部分:

  1. 魔数和Class文件的版本:文件开头是魔数(magic number),用于标识这是一个Class文件,紧接着是Class文件的版本号,包括主版本号和次版本号。

  2. 常量池:常量池是Class文件的资源仓库,用于存放编译期生成的各种字面量和符号引用。常量池中的常量数量不固定,因此在常量池入口需要放置一个u2类型的数据来表示常量池容量计数值(从1开始计数)。

  3. 访问标志:紧接着常量池的是访问标志,用于识别类或接口的访问信息,如是否为public、abstract、final等。

  4. 类索引、父类索引与接口索引集合:这三项数据用于确定类的继承关系,包括类的全限定名、父类的全限定名以及实现的接口列表。

  5. 字段表:用于描述类或接口中声明的变量,包括类级变量和实例级变量。

  6. 方法表:方法表的结构类似于字段表,用于描述类中的方法信息。方法的具体实现(字节码指令)存储在方法属性表中的Code属性里。

  7. 属性表:Class文件、字段表、方法表都可以携带自己的属性表集合,用于描述某些场景专有的信息。

二、详细解析

1. 魔数和Class文件的版本
  • 魔数:Class文件的开头是4个字节的魔数(CAFEBABE),用于标识这是一个Class文件。
  • 版本号:紧接着魔数的4个字节存储的是Class文件的版本号,包括主版本号和次版本号。JDK1.2~JDK12之间次版本号都为0,JDK12以后重新启用了次版本号。
2. 常量池
  • 作用:常量池是Class文件的资源仓库,主要存放两大类常量:字面量和符号引用。
  • 字面量:包括文本字符串、声明为final的常量值等。
  • 符号引用:包括类和接口的全限定名、字段的名称和描述符、方法的名称和描述符等。
  • 编号:常量池中的每个常量都有一个唯一的编号(从1开始),在字段和方法的字节码指令中通过常量编号来引用常量。
3. 访问标志
  • 作用:用于识别类或接口的访问信息,如是否为public、abstract、final等。
  • 标志值:如ACC_PUBLIC(0x0001)、ACC_FINAL(0x0010)、ACC_INTERFACE(0x0200)等。
4. 类索引、父类索引与接口索引集合
  • 类索引:指向常量池的一个索引,用于确定类的全限定名。
  • 父类索引:指向常量池的一个索引,用于确定类的父类全限定名。所有Java类(除了java.lang.Object)都有父类,因此父类索引不为0。
  • 接口索引集合:一个指向常量池中所有接口全限定名的容器,用于描述类实现的接口列表。
5. 字段表和方法表
  • 字段表:用于描述类或接口中声明的变量,包括字段的作用域、是否为static、是否为final、是否为volatile、是否可序列化等信息。
  • 方法表:用于描述类中的方法信息,包括方法的访问标志、名称索引、描述符索引等。方法的具体实现(字节码指令)存储在方法属性表中的Code属性里。
6. 属性表
  • 作用:Class文件、字段表、方法表都可以携带自己的属性表集合,用于描述某些场景专有的信息。
  • 预定义属性:如Code属性(存储方法的字节码指令)、ConstantValue属性(存储final字段的常量值)、Exceptions属性(存储方法抛出的异常列表)等。

字节码

jvm 中的指令是由操作码和其后的操作数构成。字节码使用大端序表示,高位在前,低位在后。

opcode [operand1, operand2]

java虚拟机的常见实现里, Hotspot 是基于栈的,DalvikVM 基于寄存器。对于 Hotspot JVM(不特殊指定,默认)每个线程都有一个虚拟机栈来存储战阵,每次方法调用都伴随栈帧的创建、销毁。

在这里插入图片描述
常见的递归方法的栈溢出就是在这里。每个栈帧有自己的局部变量表、操作数栈(Operand Stack)和指向常量池的引用。

1.局部变量表
每个栈帧内部都包含一组称为局部变量表的变量列表,局部变量表的大小在编译期间就已经确定,对应class文件中方法Code属性的maxlocals字段,Java虚拟机会根据maxlocals字段来分配方法执行过程中需要分配的最大的局部变量表容量。
2.操作数栈
每个栈帧内部都包含一个称为操作数栈的后进先出(LIFO)栈,栈的大小同样也是在编译期间确定。Java虚拟机提供的很多字节码指令用于从局部变量表或者对象实例的字段中复制常量或者变量到操作数栈,也有一些指令用于从操作数栈取走数据、操作数据和把操作结果重新入栈。在方法调用时,操作数栈也用于准备调用方法的参数和接收方法返回的结果。

字节码指令

加载(load)和存储(store)相关的指令是使用得最频繁的指令,分为1oad类、store类常量加载这三种。
1)load 类指令是将局部变量表中的变量加载到操作数栈。
2)store 类指令是将栈顶的数据存储到局部变量表中。
3)常量加载相关的指令,常见的有const类、push类、ldc类。const、push 类指令是将常量值直接加载到操作数栈顶。

方法执行:
invokestatic:用于调用静态方法。
invokespecial:用于调用私有实例方法、构造器方法以及使用super 关键字调用父类的实例方法等。
invokevirtual:用于调用非私有实例方法。
invokeinterface:用于调用接口方法。

Spotbugs

上面的基础概念了解之后,下面对应一下

    String calledClassName = getClassConstantOperand();   //   类名String calledMethodName = getNameConstantOperand();//  方法名String calledMethodSig = getSigConstantOperand();//   方法签名

参考资料:
《/深入理解JVM字节码》

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

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

相关文章

Linux基于centOS7 【进度条】【Git】【gdb】学习

目录 进度条 进度条的前置准备 sleep (秒)& usleep(微秒) sleep加\n和不加\n的区别 IO函数的缓冲区 回车&换行 10秒倒计时 进度条编写 git的使用 为什么要有git(git版本控制器) git的主要…

江科大/江协科技 STM32学习笔记P13

文章目录 TIM定时中断1、TIM简介计数器PSC预分频器ARR自动重装寄存器 2、定时器类型基本定时器主模式触发DAC 通用定时器高级定时器 3、定时器原理定时中断基本结构预分频器时序计数器时序RCC时钟树 TIM定时中断 1、TIM简介 定时器的基准时钟一般都是主频72MHz,如果…

业绩增长新引擎:智能名片如何助力销售突破

01、智能名片,营销增长利器 在当今竞争激烈的市场环境下,企业正面临着类似品牌曝光不足、销售线索获取困难、客户关系维护复杂等诸多挑战。为帮助企业解决相关难题,促进业绩高效增长,纷享营销通的 智能名片 应运而生&#xff0…

Leetcode—74. 搜索二维矩阵【中等】

2024每日刷题&#xff08;149&#xff09; Leetcode—74. 搜索二维矩阵 实现代码 class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {int m matrix.size();int n matrix[0].size();int l 0;int r m * n;int mid -1…

DB-gpt + one-api + kimi-free-api 真香

# 1. 新建文件夹 one-api 和 子目录 mkdir -p /docker/one-api/data# 运行容器one-api docker run --name one-api -d --restart always -p 3333:3000 \ -e TZAsia/Shanghai -e REDIS_CONN_STRINGredis://192.168.0.3:6379 -e SYNC_FREQUENCY60 -e SQL_DSNroot:123456tcp(192.1…

springboot整合junit-用于测试用例

package impl;public interface BookDao {public void save(); }第一步&#xff1a;打开软件&#xff0c;点击file&#xff0c;点击new 然后选择module&#xff0c;在右侧选择springboot 第二步&#xff1a;选择配置和JDK以及java版本 ①选择maven类型 ②选择JDK1.8版本 ③选…

极限两边夹定理

极限两边夹定理 1. 定义 两边夹定理 (又称作夹逼定理) 说的是&#xff0c;如果一个函数 f f f 被夹在函数 g g g 和函数 h h h 之 间&#xff0c;当 x → a x \rightarrow a x→a 时&#xff0c;这两个函数 g g g 和 h h h 都收敛于同一个极限 L L L&#xff0c;那么当…

全国区块链职业技能大赛样题第9套后端源码

后端源码地址:https://blog.csdn.net/Qhx20040819/article/details/140746050 前端源码地址:https://blog.csdn.net/Qhx20040819/article/details/140746216 智能合约+数据库表设计:https://blog.csdn.net/Qhx20040819/article/details/140746646 项目预览 登录 用户管理

LRTimelapse Pro 7.0 安装教程

软件介绍 LRTimelapse Pro (LRT) 是一款专业的延迟摄影编辑渲染工具&#xff0c;具有高清输出、简单易用、无缝转换等特点。是非常强大的一款延迟摄影工具&#xff01;LRTimelapse Pro可以将您的影片提升一个水准。 程序可以配合 Adobe Lightroom, Adobe Camera RAW 和 Adobe…

2024年孝感中级职称报名开始了吗?

2024年孝感中级职称申报终于开始了&#xff0c;之前参加过水测的小伙伴们&#xff0c;开始准备评审了 2024年孝感本批次申报时间&#xff1a;中级、初级职称网上申报时间:2024年8月1日至8月31日。 注意&#xff1a;个人通过“湖北省职称评审管理信息系统”申报&#xff0c;须先…

Llama 3.1 重磅发布,登顶开源大模型王座!

7月23日&#xff0c;Meta正式发布迄今为止最强大的开源模型——Llama 3.1 405B&#xff0c;同时发布了全新升级的Llama 3.1 70B和8B模型。 Meta在正式发布里也附上了长达92页的论文《The Llama 3 Herd of Models》&#xff0c;揭示了Llama 3模型的技术和训练细节。 论文地址&am…

Jacoco 单元测试配置

前言 编写单元测试是开发健壮程序的有效途径&#xff0c;单元测试写的好不好可以从多个指标考量&#xff0c;其中一个就是单元测试的覆盖率。单元测试覆盖率可以看到我们的单元测试覆盖了多少代码行、类、分支等。查看单元测试覆盖率可以使用一些工具帮助我们计算&#xff0c;…

图解RocketMQ之生产者如何进行消息重试

大家好&#xff0c;我是苍何。 上一篇留了一个小问题&#xff0c;如果消费者出现异常&#xff0c;消费某一条消息失败&#xff0c;这时候 RocketMQ 会怎么处理呢&#xff1f; 你可能会用你聪明绝顶的脑袋瓜子想&#xff0c;苍何你是不是傻&#xff0c;失败了肯定重试啊&#…

单据新增,限制单据栏位的录入值,设置过滤条件

希望通过开发实现 单据头的组织栏位,只能选择101开头的组织,实现的效果如下: 代码如下: using Kingdee.BOS.Util; using Kingdee.BOS.Core.DynamicForm.PlugIn; using Kingdee.BOS.Core.DynamicForm.PlugIn.Args; using System.ComponentModel;namespace cux.button.test {…

基于opencv的人脸识别(实战)

前言 经过这几天的学习&#xff0c;我已经跃跃欲试了&#xff0c;相信大家也是&#xff0c;所以我决定自己做一个人脸识别程序。我会把自己的思路和想法都在这篇博客内讲清楚&#xff0c;大家可以当个参考&#xff0c;&#x1f31f;仅供学习使用&#x1f31f;。 &#x1f31f…

分享10个好用的论文编辑服务/平台

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 如果您对自己的学术写作能力存在怀疑&#xff0c;论文编辑服务/平台或许能提供帮助。为了帮助您做出更好的选择&#xff0c;今天的分享我们列出了2024年“全网”最好用的10个论文编辑服…

怎么样建设数字化车间?

建设数字化车间是一个综合性的过程&#xff0c;旨在通过现代信息技术、智能设备和自动化技术对车间进行优化改造&#xff0c;提高生产效率和产品质量。以下是一些关键步骤和要点&#xff0c;用于指导数字化车间的建设&#xff1a; 一、明确建设目标和需求 分析现状&#xff1…

【轨物方案】开关柜在线监测物联网解决方案

随着物联网技术的发展&#xff0c;电力设备状态监测技术也得到了迅速发展。传统的电力成套开关柜设备状态监测方法主要采用人工巡检和定期维护的方式&#xff0c;这种方法不仅效率低下&#xff0c;而且难以保证设备的实时性和安全性。因此&#xff0c;基于物联网技术的成套开关…

Mybatis-Plus-常用的注解:@TableName、@TableId、@TableField、@TableLogic

1、TableName 经过之前的测试&#xff0c;在使用MyBatis-Plus实现基本的CRUD时&#xff0c;我们并没有指定要操作的表&#xff0c;只是在Mapper接口继承BaseMapper时&#xff0c;设置了泛型User&#xff0c;而操作的表为user表由此得出结论&#xff0c;MyBatis-Plus在确定操作…

Python:随机数、随机选择的应用

step1:导入 导入的random相当于是创建了random文件里的的一个对象 import random random() 产生0~1随机数 randint(a,b)产生a~b的整数 闭区间&#xff0c;可以取到a,b random.choice(touple_name)从touple_name&#xff08;数组、列表..&#xff09;中随机选择元素 import rand…