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

news2024/9/8 11:39:14

文章目录

    • 一、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.coloradmin.cn/o/1961676.html

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

相关文章

DRAM 和 NAND 闪存收入将在 2024 年显著增长 75% 和 77%

#### 市场概况 根据 TrendForce 最新发布的市场报告,预计 2024 年 DRAM 和 NAND 闪存的收入将分别显著增长 75% 和 77%,这一增长主要是由于平均价格的上涨以及高价值产品的兴起,例如 HBM(高带宽内存)和 QLC&#xff0…

卷积神经网络(六)---实现 cifar10 分类

cifar10 数据集有60000张图片,每张图片的大小都是 32x32 的三通道的彩色图,一共是10种类别、每种类别有6000张图片,如图4.27所示。 图 4.27 cifar数据集 使用前面讲过的残差结构来处理 cifar10 数据集,可以实现比较高的准确率。 …

配置本地开发服务器代理请求以及登录模块开发(二)

项目初始化完成之后,准备开始进行项目的开发,首先配置好开发环境作为整个项目的基础 一、配置代理 1、config/proxy.ts配置代理 export default {// 如果需要自定义本地开发服务器 请取消注释按需调整dev: {// localhost:8000/api/** -> https://p…

Seata 入门与实战

一、什么是 Seata Seata 是一款开源的分布式事务解决方式,致力于提供高性能和简单易用的分布式事务服务。Seata 为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式事务解决方案。 二、Seata 组成 事务协调者(Transacti…

什么是Shell?怎么编写和执行Shell脚本?

大家好呀!今天来简单介绍一下Shell基础,Shell介于内核与用户之间,是一个命令解释器,负责命令的解释。简单理解,Shell既是一个程序也是一种脚本语言。 1、shell介绍 1.1 概述 shell介于内核与用户之间,是一个…

索引结构—B+Tree索引、Hash索引、Full-Text(全文)索引、R-Tree(空间)索引

一、概述 在数据库系统中,索引是一种用于加快数据检索的数据结构。不同的索引结构适用于不同的查询场景和数据特性。索引按照不同角度可以划分不同类型的索引。按照数据结构可以划分BTree索引、Hash索引、FULL TEXT(全文)索引、R-Tree&#…

python inf是什么意思

INF / inf:这个值表示“无穷大 (infinity 的缩写)”,即超出了计算机可以表示的浮点数的范围(或者说超过了 double 类型的值)。例如,当用 0 除一个整数时便会得到一个1.#INF / inf值;相应的,如果…

卡码网KamaCoder 103. 水流问题

题目来源&#xff1a;103. 水流问题 C题解&#xff1a;从边界往高处走&#xff0c;走过的地方做标记。第一组边界跟第二组边界能走到的地方取交集。 代码来源代码随想录。&#xff08;虽然思路一样&#xff0c;但人家代码写得比我好哇&#xff09; #include <iostream>…

pyinstaller带浏览器一起打包playwright 独立运行exe

前置条件 没有安装自带环境&#xff0c;则 playwright install 安装了自带的浏览器 查看playwright的浏览器的位置 playwright install --dry-run 打开此文件夹可以看到 新建一个多层级目录playwright\driver\package.local-browsers 然后复制chromium-1124到playwright\dr…

听说它可以让代码更优雅

一提到静态代码检查工具这个词应该比较好理解&#xff0c;所谓静态代码检查工具就是检查静态代码的工具&#xff0c;完美~ 言归正传&#xff0c;相信很多程序员朋友都听说过静态代码检查工具这个概念&#xff0c;它可能是我们IDE里的某一个插件&#xff0c;可能是计算机中的一…

比 faster-whisper 至少快10倍的音视频转换文字

背景介绍 前两天我自己玩玩搞搞一个音频转文字服务&#xff0c;基于 faster-whisper&#xff0c;本想着这个已经是很快的了&#xff0c;没想到还有比它更快的&#xff0c;今天就来介绍使用一下。 FunClip&#xff0c;是阿里巴巴推出的一个智能视频剪辑工具&#xff0c;它结合…

计算机毕业设计选题推荐-某炼油厂盲板管理系统-Java/Python项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

[Bugku] web-CTF靶场详解!!!

平台为“山东安信安全技术有限公司”自研CTF/AWD一体化平台&#xff0c;部分赛题采用动态FLAG形式&#xff0c;避免直接抄袭答案。 平台有题库、赛事预告、工具库、Writeup库等模块。 ------------------------------- Simple_SSTI_1 启动环境&#xff1a; 页面提示传入参数f…

【Qt】QLCDNumberQProgressBarQCalendarWidget

目录 QLCDNumber 倒计时小程序 相关属性 QProgressBar 进度条小程序 相关设置 QLCDNumber QLCDNumber是Qt框架中用于显示数字或计数值的小部件。通常用于显示整数值&#xff0c;例如时钟、计时器、计数器等 常用属性 属性说明intValueQLCDNumber显示的初始值(int类型)va…

【全面介绍下Gitea,什么是Gitea?】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

这几个高级爬虫软件和插件真的强!

亮数据&#xff08;Bright Data&#xff09; 亮数据是一款强大的数据采集工具&#xff0c;以其全球代理IP网络和强大数据采集技术而闻名。它能够轻松采集各种网页数据&#xff0c;包括产品信息、价格、评论和社交媒体数据等。 网站&#xff1a;https://get.brightdata.com/we…

ubuntu安装并配置flameshot截图软件

参考&#xff1a;flameshot key-bindins 安装 sudo apt install flameshot自定义快捷键 Settings->Keyboard->View and Customize Shortcuts->Custom Shortcuts&#xff0c;输入该快捷键名称&#xff08;自定义&#xff09;&#xff0c;然后输入command&#xff08;…

RFID物流智能锁在物流锁控领域的意义与应用

在当今全球化和电子商务迅速发展的时代&#xff0c;物流行业作为经济的重要支撑&#xff0c;面临着日益增长的安全、效率和管理需求。物流锁控作为保障货物在运输过程中安全与完整的关键环节&#xff0c;传统的机械锁和简单电子锁已经难以满足现代物流复杂多变的业务场景。 一、…

前缀表达式(波兰式)和后缀表达式(逆波兰式)的计算方式

缀是指操作符。 1. 前缀表达式&#xff08;波兰式&#xff09; &#xff08;1&#xff09;不需用括号&#xff1b; &#xff08;2&#xff09;不用考虑运算符的优先级&#xff1b; &#xff08;3&#xff09;操作符置于操作数的前面。&#xff08;如 3 2 &#xff09; 1.1 中…

3.5.3、查找和排序算法-插入类排序和选择类排序

术语说明 稳定&#xff1a;如果a原本在b前面&#xff0c;而ab,排序之后a仍然在b的前面&#xff1b; 不稳定&#xff1a;如果a原本在b的前面&#xff0c;而ab,排序之后a可能会出现在b的后面&#xff1b; 例如&#xff1a;数组{1,2,3,3,4,7,6}。如果排序后&#xff0c;两个3的位…