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

类字节码:揭开Java虚拟机运行机制的神秘面纱

概述计算机是不能直接运行java代码的必须要先运行java虚拟机再由java虚拟机运行编译后的java代码。因为在cpu层面看来计算机中所有的操作都是一个个指令的运行汇集而成的java是高级语言只有人类才能理解其逻辑计算机是无法识别的所以java代码必须要先编译成字节码文件jvm才能正确识别代码转换后的指令并将其运行。Java代码间接翻译成字节码储存字节码的文件再交由运行于不同平台上的JVM虚拟机去读取执行从而实现一次编写到处运行的目的。Java字节码文件class文件本质上是一个以8位字节为基础单位的二进制流各个数据项目严格按照顺序紧凑的排列在class文件中。jvm根据其特定的规则解析该二进制数据从而得到相关信息。Class文件的结构属性反编译字节码文件javac 生成字节码文件javap 反编译字节码文件javap用法-help --help -? 输出此用法消息 -version 版本信息 -v -verbose 输出附加信息 -l 输出行号和本地变量表 -public 仅显示公共类和成员 -protected 显示受保护的/公共类和成员 -package 显示程序包/受保护的/公共类 和成员 (默认) -p -private 显示所有类和成员 -c 对代码进行反汇编 -s 输出内部类型签名 -sysinfo 显示正在处理的类的 系统信息 (路径, 大小, 日期, MD5 散列) -constants 显示最终常量 -classpath path 指定查找用户类文件的位置 -cp path 指定查找用户类文件的位置 -bootclasspath path 覆盖引导类文件的位置反编译//Main.java public class Main { private int m; public int inc() { return m 1; } }对以上例子输入命令javap -verbose -p Main.class查看输出内容:Classfile /E:/JavaCode/TestProj/out/production/TestProj/com/rhythm7/Main.class Last modified 2018-4-7; size 362 bytes MD5 checksum 4aed8540b098992663b7ba08c65312de Compiled from Main.java public class com.rhythm7.Main minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 Methodref #4.#18 // java/lang/Object.init:()V #2 Fieldref #3.#19 // com/rhythm7/Main.m:I #3 Class #20 // com/rhythm7/Main #4 Class #21 // java/lang/Object #5 Utf8 m #6 Utf8 I #7 Utf8 init #8 Utf8 ()V #9 Utf8 Code #10 Utf8 LineNumberTable #11 Utf8 LocalVariableTable #12 Utf8 this #13 Utf8 Lcom/rhythm7/Main; #14 Utf8 inc #15 Utf8 ()I #16 Utf8 SourceFile #17 Utf8 Main.java #18 NameAndType #7:#8 // init:()V #19 NameAndType #5:#6 // m:I #20 Utf8 com/rhythm7/Main #21 Utf8 java/lang/Object { private int m; descriptor: I flags: ACC_PRIVATE public com.rhythm7.Main(); descriptor: ()V flags: ACC_PUBLIC Code: stack1, locals1, args_size1 0: aload_0 1: invokespecial #1 // Method java/lang/Object.init:()V 4: return LineNumberTable: line 3: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom/rhythm7/Main; public int inc(); descriptor: ()I flags: ACC_PUBLIC Code: stack2, locals1, args_size1 0: aload_0 1: getfield #2 // Field m:I 4: iconst_1 5: iadd 6: ireturn LineNumberTable: line 8: 0 LocalVariableTable: Start Length Slot Name Signature 0 7 0 this Lcom/rhythm7/Main; } SourceFile: Main.java字节码文件信息开头的7行信息包括:Class文件当前所在位置最后修改时间文件大小MD5值编译自哪个文件类的全限定名jdk次版本号主版本号。然后紧接着的是该类的访问标志ACC_PUBLIC, ACC_SUPER访问标志的含义如下:常量池Constant pool意为常量池。主要存放的是两大类常量字面量(Literal)和符号引用(Symbolic References)。字面量类似于java中的常量概念如文本字符串final常量而符号引用则属于编译原理方面的概念包括以下三种:类和接口的全限定名(Fully Qualified Name)字段的名称和描述符号(Descriptor)方法的名称和描述符常量池与运行时常量池常量池就是一张表如上图中的constant pool虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量信息运行时常量池常量池是*.class文件中的当该类被加载以后JVM才进行的动态链接也就是说在运行期转换后它的常量池信息就会放入运行时常量池并把里面的符号地址变为真实地址#1 Methodref #4.#18 // java/lang/Object.init:()V #4 Class #21 // java/lang/Object #7 Utf8 init #8 Utf8 ()V #18 NameAndType #7:#8 // init:()V #21 Utf8 java/lang/Object第一个常量是一个方法定义指向了第4和第18个常量。以此类推查看第4和第18个常量。最后可以拼接成第一个常量右侧的注释内容:java/lang/Object.init:()V这段可以理解为该类的实例构造器的声明由于Main类没有重写构造方法所以调用的是父类的构造方法。此处也说明了Main类的直接父类是Object。 该方法默认返回值是V, 也就是void无返回值。第二个常量同理可得:#2 Fieldref #3.#19 // com/rhythm7/Main.m:I #3 Class #20 // com/rhythm7/Main #5 Utf8 m #6 Utf8 I #19 NameAndType #5:#6 // m:I #20 Utf8 com/rhythm7/Main此处声明了一个字段m类型为I, I即是int类型。关于字节码的类型对应如下对于数组类型每一位使用一个前置的 [ 字符来描述如定义一个java.lang.String[][] 类型的维数组将被记录为 [[Ljava/lang/Strin方法表集合在常量池之后的是对类内部的方法描述在字节码中以表的集合形式表现private int m; descriptor: I flags: ACC_PRIVATE此处声明了一个私有变量m类型为int返回值为intpublic com.rhythm7.Main(); descriptor: ()V flags: ACC_PUBLIC Code: stack1, locals1, args_size1 0: aload_0 1: invokespecial #1 // Method java/lang/Object.init:()V 4: return LineNumberTable: line 3: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom/rhythm7/Main;这里是构造方法Main()返回值为void, 公开方法。code内的主要属性为:stack: 最大操作数栈JVM运行时会根据这个值来分配栈帧(Frame)中的操作栈深度,此处为1locals: 局部变量所需的存储空间单位为Slot, Slot是虚拟机为局部变量分配内存时所使用的最小单位为4个字节大小。方法参数(包括实例方法中的隐藏参数this)显示异常处理器的参数(try catch中的catch块所定义的异常)方法体中定义的局部变量都需要使用局部变量表来存放。值得一提的是locals的大小并不一定等于所有局部变量所占的Slot之和因为局部变量中的Slot是可以重用的。args_size: 方法参数的个数这里是1因为每个实例方法都会有一个隐藏参数thisattribute_info: 方法体内容0,1,4为字节码行号该段代码的意思是将第一个引用类型本地变量推送至栈顶然后执行该类型的实例方法也就是常量池存放的第一个变量也就是注释里的java/lang/Object.)V, 然后执行返回语句结束方法。LineNumberTable: 该属性的作用是描述源码行号与字节码行号(字节码偏移量)之间的对应关系。可以使用 -g:none 或-g:lines选项来取消或要求生成这项信息如果选择不生成LineNumberTable当程序运行异常时将无法获取到发生异常的源码行号也无法按照源码的行数来调试程序。LocalVariableTable: 该属性的作用是描述帧栈中局部变量与源码中定义的变量之间的关系。可以使用 -g:none 或 -g:vars来取消或生成这项信息如果没有生成这项信息那么当别人引用这个方法时将无法获取到参数名称取而代之的是arg0, arg1这样的占位符。start 表示该局部变量在哪一行开始可见length表示可见行数Slot代表所在帧栈位置Name是变量名称Signature 类型签名方法体内的内容是将this入栈获取字段#2并置于栈顶, 将int类型的1入栈将栈内顶部的两个数值相加返回一个int类型的值。字节码的好处编译型与解释型采用字节码的好处java程序通过编译器编译成字节码文件也就是计算机可以识别的二进制。java虚拟机就是将字节码文件解释成二进制段。采用字节码的最大好处是可以实现一次编译到处运行也就是java的与平台无关性编译型编译型语言open in new window 会通过编译器open in new window将源代码一次性翻译成可被该平台执行的机器码。一般情况下编译语言的执行速度比较快开发效率比较低。常见的编译性语言有 C、C、Go、Rust 等等。解释型解释型语言open in new window会通过解释器open in new window一句一句的将代码解释interpret为机器代码后再执行。解释型语言开发效率比较快执行速度比较慢。常见的解释性语言有 Python、JavaScript、PHP 等等。Java 语言“编译与解释并存”这是因为 Java 语言既具有编译型语言的特征也具有解释型语言的特征。因为 Java 程序要经过先编译后解释两个步骤由 Java 编写的程序需要先经过编译步骤生成字节码.class 文件这种字节码必须由 Java 解释器来解释执行文章转载自Seven原文链接https://www.cnblogs.com/sevencoding/p/19682267体验地址http://www.jnpfsoft.com/?from001YH

相关文章:

类字节码:揭开Java虚拟机运行机制的神秘面纱

概述 计算机是不能直接运行java代码的,必须要先运行java虚拟机,再由java虚拟机运行编译后的java代码。 因为在cpu层面看来计算机中所有的操作都是一个个指令的运行汇集而成的,java是高级语言,只有人类才能理解其逻辑&#xff0c…...

同样是 GIS 开发,为什么有人月薪 8K,有人 20K+?

通常来说,GIS开发薪资和很多方面的因素有关,公司所在城市、行业;面试者的学历、工作经验、项目经验等。 尤其是首次找工作,很多人反馈对GIS开发薪资最大的一个影响因素就是工作经验和项目经验。 今天我们来看下,不同…...

Windows系统借助Docker部署Dify完整教程

写在前面: 近年来,人工智能技术正在快速进入各行各业。从ChatGPT、Claude、Gemini 等大模型的爆发,到企业内部AI智能助手、自动化客服、数据分析智能体的落地,越来越多的开发者开始关注如何快速构建自己的AI应用和智能体&#xff…...

PTA 树与二叉树 3 中序+后序序列构建二叉树

作者 张鏖烽单位 湖南工程学院(1)根据某二叉树的后序中序遍历序列,构建出这棵二叉树;(2)输出二叉树bt中等于ch的结点的所有祖先结点;(3)输出二叉树bt中所有单分支结点&am…...

轮毂电机分布式驱动车辆状态估计:EKF 与 UKF 的探索

车辆状态估计,扩展卡尔曼滤波EKF,无迹卡尔曼滤波UKF 角阶跃输入整车7自由度模型UKF状态估计模型附送EKF状态估计模型,针对于轮毂电机分布式驱动车辆,进行车速,质心侧偏角,横摆角速度估计。 模型输入&#x…...

jsch 升级 0.2.x 版本对 bcprov-jdk 的依赖分析

背景 某应用使用 jsch 0.1.x 版本进行 SFTP 操作,某主机上连接时出现了 com.jcraft.jsch.JSchException: Algorithm negotiation fail 算法协商异常,解决思路是升级 jsch 为 0.2.x 版本,但是工程中又有两种 org.bouncycastle.crypto 包的实现…...

基于yolov26的多光谱成像的焊缝质量实时检测系统

目录 系统架构设计 数据预处理 网络架构 实时推理优化涉及模型压缩 脚本1:多模态数据预处理与图像配准 脚本2:双分支YOLOv26主干网络架构 脚本3:跨模态特征融合与注意力机制实现 脚本4:训练流程与多模态损失函数 脚本5:实时推理与部署优化 基于多光谱成像的焊缝质…...

PostBot 内容同步助手

PostBot 内容同步助手 它是一款开源的多平台内容同步分发生产力工具。 支持将文章、笔记、动态、图片、视频、音频等内容,一键同步发布至主流媒体平台。 覆盖微信/微博/今日头条/小红书/知乎/百家号/企鹅号/视频号/抖音/快手/哔哩哔哩(B站)等…...

科研绘图还在啃软件?Paperxie AI:一句话生成学术图表,流程图 / CAD 图全搞定

paperxie科研绘图https://www.paperxie.cn/drawinghttps://www.paperxie.cn/drawing 在学术圈流传着这样一句话:「论文写得好,不如图画得巧」。一张清晰规范的图表,不仅能让审稿人眼前一亮,更是科研成果可视化的核心载体。但现实是…...

纯电动汽车动力经济性仿真:Cruise 与 Simulink 联合仿真探索

纯电动汽车动力经济性仿真,Cruise和Simulink联合仿真,提供Cruise整车模型和simuink策略模型,策略主要为BMS、再生制动和电机驱动策略,内含注释模型和详细解析文档,可运行!在电动汽车研发领域,动…...

MySQL 数据库在自动测试系统中的应用研究

摘要:MySQL数据库具有原子性、一致性、隔离性、持久性等基本特性,作为关系型数据库的代表被广泛应用于不同行业自动测试系统的设计与开发环节,在测试模块选择、测试系统创新等方面为用户提供工具支持。通过基于 LabVIEW 开发平台进行数据库访…...

探索双级式储能模型:充放电转换、低电压故障穿越与负序抑制

双级式储能模型,可做充放电转换以及低电压故障穿越,含有负序抑制模块,可做对称故障与不对称故障最近一直在研究一个超酷的双级式储能模型,感觉有好多有趣的东西想和大家分享😃。这个双级式储能模型功能可强大啦&#x…...

三部六层电梯仿真群控联动系统:基于西门子S7-1200 PLC与博图v15.1及以上版本实现方...

三部六层电梯,基于西门子1200,博图v15.1版本及以上,群控联动带算法,可直接仿真运行,不用下载到实物,需要报告另加, 清单如下: Wincc组态 Plc程序 图纸真实i Q Io表 内部变量m 主讲程…...

淘宝系逆向@阿里巴巴商家版-转人工逆向

转交功能是其他功能中较为复杂的一个,它的复杂度在于构造转交类对象,其难度主要有3点:1、 如何实现减少call的情况下,成功构造转交类对象?a.其实就是通过填充类对象数据,只需要一个call即可实现转交类对象的…...

sdut-程序设计基础Ⅰ-实验四for循环(11-22)

7-11 sdut-C语言实验- 平方数飞飞特别喜欢平方数,可是他数学并不好,你能帮他计算 n 与 m 之间所有平方数之和吗? 提示1:若一个整数的开方还是整数,它就是平方数。例如:4、9、16、25是平方数。n 和 m 均可能…...

谈工业品迭代规律与开发者创业逻辑

一、起点:从解决一个具体的痛点开始 马斯克大学毕业时没什么钱,他观察到一个现象:传统媒体行业有钱,但面临数字化转型的痛点。于是他做了一个软件,为报纸提供在线城市地图和分类目录。这家公司后来被康柏收购&#xff…...

一文读懂安森美超低功耗,超强性能,支持边缘AI开发的双模蓝牙芯片

NCH-RSL20- 103WC61-ABG (下文简称RSL20)是安森美半导体于2026年2月刚发布的一颗2.4GHz超低功耗双模蓝牙芯片(也就是说,它支持经典蓝牙的BR与EDR,A2DP,HFP以及低功耗蓝牙的LE audio Auracast™)&#xff0c…...

flink-yarn提交任务,application无限次appattempt

一般大家都推荐配置yarn.resourcemanager.am.max-attempts、yarn.application-attempt-failures-validity-interval和yarn.application-attempts 但是在yarn-site.xml里配置了却没生效哈哈 不生效的原因是因为flink提交application 时候fink会通过反射给yarn传过去,…...

停车场烟雾报警组态监控系统的设计与实现

4#基于三菱PLC组态王16停车场烟雾报警组态监控系统停车场作为人员和车辆聚集的重要场所,其安全问题一直是管理工作的重点。烟雾报警系统作为防火的重要手段,能够及时发现火情,最大限度地减少损失。本文将介绍基于三菱PLC和组态王16的停车场烟…...

方达炬 发明新字词:人市比

方达炬 发明新字词:人市比...

方盾在口,安全在手:煤矿半面罩的职业健康使命

煤矿开采是中国能源供应的重要支柱。然而,煤矿作业环境复杂,空气中悬浮着大量煤尘、岩尘及有害气体。这些污染物对矿工呼吸系统构成严重威胁。长期吸入煤尘可导致尘肺病等不可逆的职业病。因此,个体防护装备的配备与使用至关重要。在众多防护…...

使用实时云渲染LarkXR顺利搭建云VR方案

Paraverse平行云自研的实时云渲染产品LarkXR,是行业内应用最广泛的企业级云渲染PaaS服务平台,具备的“云-网-端-PaaS平台“属性,支持私有化/公有云部署,支持全终端覆盖。 平行云秉持开发者友好的理念,多年来持续运营开…...

2026年呼和浩特靠谱瓷砖大揭秘!哪种款式数量多你知道吗?

嘿,家人们!在呼和浩特准备装修的朋友们,是不是正在为选瓷砖而发愁呢?今天咱就来好好唠唠2026年呼和浩特靠谱的瓷砖,顺便揭秘一下哪种款式数量多。一、瓷砖市场乱象,你怕了吗?现在瓷砖市场鱼龙混…...

Godot游戏练习01-第10节-组件化,玩家受伤,YSort,和一点思考

今天将"伤害"与"受伤"功能组件化, 并且在玩家身上实现受伤机制, 同时也能体会组件化的好处, 最后实现了Player与Enemy之间的YSort效果 本次实现的内容主要体现在组件化与复用, 可观察的内容并不多 看看效果 之前的实现中, 无论Player与Enemy处于什么样的相…...

QT使用ui->checkBox->setChecked(true)时,注意事项

QT界面上拖入一个checkBox组件,定义了stateChanged槽函数,即checkBox勾选框状态发生变化的时候,触发stateChanged函数。 如果没有设置勾选框默认状态时,勾选框默认是未勾选的状态,当用代码 ui->checkBox->setChe…...

出海必备跨境电商短视频群控系统怎么选?新手必看方法!

刚起步的出海卖家是不是总卡在这?想铺社媒矩阵做短视频营销,拍一条视频要租场地、找外籍模特,一周出不了10条;投到TikTok、亚马逊、Shopify不同平台,还要手动改格式、调风格,折腾半天还不符合平台规则&…...

从入门到精通Python:零基础可落地的学习指南,解锁2026年编程新机遇

在数字化浪潮席卷全球的今天,Python早已不再是程序员专属的“工具语言”,而是成为跨行业的“通用技能”——从互联网大厂的后端开发、人工智能训练,到职场人的自动化办公、数据分析,再到科研领域的建模仿真,Python以其…...

【论文解读】隐马尔可夫模型:语音识别领域的奠基之作

玄同 765 大语言模型 (LLM) 开发工程师 | 中国传媒大学 数字媒体技术(智能交互与游戏设计) CSDN 个人主页 | GitHub Follow 关于作者 深耕领域:大语言模型开发 / RAG 知识库 / AI Agent 落地 / 模型微调技术栈:Python | R…...

使用Conda和pip创建Python环境

使用Conda和pip创建Python环境添加阿里云镜像源安装环境问题添加阿里云镜像源 conda config --add channels https://mirrors.aliyun.edu.cn/anaconda/pkgs/free/ conda config --add channels https://mirrors.aliyun.edu.cn/anaconda/pkgs/main/ conda config --add channel…...

基于Matlab Simulink的4WID-4WIS整车动力学14自由度模型构建与应用指南

4WID-4WIS整车动力学14自由度模型_simulink软件使用:Matlab/Simulink 适用场景:采用模块化建模方法,搭建14自由度四轮驱动-四轮转向整车动力学模型,作为整车平台适用于多种工况场景。 产品simulink源码包含如下模块: →…...