首页 > 其他分享 >字节码文件解剖

字节码文件解剖

时间:2024-07-05 16:33:46浏览次数:10  
标签:文件 java 常量 aaa 解剖 string 字节

#### 前提提要:

.java文件通过java -c 生成.class文件,这部分并非是JVM需要处理的部分,JVM处理的部分是基于生成的class文件,生成的部分是由编译器来负责

一个字节码文件的主要组成部分

image-20240705134632708

使用工具说明

idea的JclassLib插件

使用步骤:

  1. 运行代码(只要你更新了代码就需要,或者build)
  2. image-20240705135213385

基础信息介绍

image-20240705134952556

魔数

魔数并非在这里展示,魔数其实有点类似一个文件的格式中的一部分,所有的软件开发中关于打开文件都会这么设计,用于识别说我们能否成功打开

java中是开头是cafebabe

其他文件如下:

image-20240705135756018

主版本号

1.2后大版本对应的公式是主版本号-44

image-20240705135921638

关于版本号可能遇到的problem及解法
  1. 版本不匹配
    1. 提高java版本
    2. 降低依赖版本

image-20240705140132316

在这之中可能还会遇到的问题:jdk版本存在bug,虽然很多人都说什么永远jdk8,但是实际使用上jdk8在性能上以及开发上可能会比jdk17多不少工作量,例如我之前尝试转为http2,而在jdk8需要引入其他依赖,而jdk9则可以直接转

常量池介绍以及属性介绍

此常量池非JVM中的字符串常量池,仅仅是当前class文件中为了降低一定的空间占用和加快JVM解析class文件而使用的常量池而已

下列讨论也仅局限于字节码文件中的常量池,不会涉及JVM部分

在此先给常量池定论:为了节省空间而使用的池化技术

首先从字段入手:

image-20240705141818983

image-20240705142237700

Problem1:为什么aaa变量可以打开?而其他的不行?

解答:是因为他使用的是static和final同时修饰

所有以cp开头的都最终指向了常量池中的一个记录,例如aaa这个变量名,以及对应的aaa的类型string,具体内容如下:

image-20240705142003501

image-20240705142022100

我们再看看ConstantValue的信息:

image-20240705142358192

problem2:这个属性名索引为何存在且为什么要是constantValue?

首先回答一下为什么要有constantvalue,这是由于我们使用final修饰了,所以最终的效果就是有了一个指向constantValue的引用,也就是我们java,字节码层面实现我们final修饰不可改变的效果,如下图所示,而这个属性值为什么存在也不言而喻了

image-20240705144543867

最后回到正题:我们可以发现当String aaa和Stirng ccc都="aaa"时,他的常量值索引都指向7

image-20240705144724267

那么7的内容是什么?7的类型是string_info,而之中又指向了8?

image-20240705144925308

8才是真正的aaa

image-20240705145000278

那么问题来了?

为什么要这么设计?

关于字段中的constant_value为什么要指向string?然后string再指向其中的一个具体的utf8_info呢?

因为最终jvm会有一个string常量池,我们要保存string和utf8_info中保存的值的关系,好方便之后我们将其存储到常量池中

追问:那为什么不直接保存在对应的string中,也即我们string不存符号引用而是直接存对应的常量?

这样的话如果有其他变量也纸箱这里应该也没问题吧?

没错,但是例如string abc="abc",对应的变量名也要存储,而java中采用的变量名的引用就指向对应的utf_8的"abc"

那么abc直接指向这个string不行吗?

可以,不过这样的话,能够更节省一些空间复杂度,但是会消耗更多的时间,尤其对于变量之后运行中的处理

总结

常量池是把对应的我们会使用到的常量抽出来,无论是各个参数或者变量名类名等等,他的核心之一就是要复用

而字段在目前阶段只会对于final static修饰的,因为目前能够处理的也只有些final和static修饰的值,其他是不行的,也就是编译阶段能处理的也就这一些了

其他字段的赋值需要之后类的生命周期在各个阶段再进行赋值

方法介绍

image-20240705152339655

其中字节码部分就是对应方法的执行流程

而异常表主要是trycatch才会有的

而杂项对应的操作数栈的深度是字节码运行之中对于操作数栈使用的时候会使用到的栈的深度(与数据结构无异,而最大深度是因为在这之中便可以计算出来)

image-20240705152458362

局部变量最大槽数是这里:也就是方法中使用的局部变量,包括参数等等

image-20240705152926361

关于属性就不赘述了,意义不大

标签:文件,java,常量,aaa,解剖,string,字节
From: https://www.cnblogs.com/seamount3/p/18286089

相关文章

  • 字节面试 用double,1.0-0.9的结果不是0.1,为什么?
    让我详细解释一下为什么1.0-0.9在二进制中不能精确表示。1.0的二进制表示1.0在二进制中可以精确表示。它的二进制表示为:1.0=1.0(二进制)0.9的二进制表示0.9是一个无法在二进制中精确表示的小数。二进制小数是通过求和1/2,1/4,1/8,1/16,...等幂次表示的。对......
  • 空洞文件
    实际上这些数据并没有被存储在磁盘上。当创建一个空洞文件时,文件系统会记录这些“空洞”,但并不会在物理介质上实际分配和保存未使用的空间,从而节省了实际的存储空间。举例来说,如果你创建一个大小为1GB的空洞文件,其中写入了大量的零字节据,实际上只有少量的数据(例如文件指针处......
  • 断点续传:使用java对大文件进行分块与合并
    通常我们下载上传的视频文件比较大。虽然https协议没有规定上传文件大小的限制,但是网络的质量,电脑硬件的参差不齐可能会导致大文件快要上传完成的时候突然断网了要重新上传,非常影响用户体验。以此我们引入了断点续传的功能。什么是断点续传呢?就是我们在上传下载文件的时候,将一个......
  • Linux 文件系统以及日志管理
    一、inode与block1.inode与block详解在文件存储硬盘上,硬盘的最小存储单位叫做“扇区”,每个为512字节。操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。这种由多个扇区组成的"块",是文件存取的最小......
  • golang go-bindata打包配置文件嵌入到二进制文件
    go-bindata打包配置文件嵌入到二进制文件项目中难免会用到一些静态资源和配置文件,但是常规打包的二进制文件无法再其他目录正常运行(静态资源和配置文件不存在)有类似需求的可以安装使用:go-bindata进行编译处理配置文件go-bindata(go-bindata)包实现将项目静态配置文件嵌......
  • linux 服务器与本地文件传输
    相信有的小伙伴在刚开始接触linux时,不知道如何把文件上传到linux中,本文介绍两种方式供大家使用(推荐使用第二种)一.scp传输scpC:\\[email protected]/root/.....使用上述指令,即可实现将制定文件传输到服务器中,其中C…以及/root/…需要换成你自己的路径。165…........
  • 探寻操作系统文件名字符限制的规则和历史
    引言从最早的电脑系统到现代的操作系统,文件命名的规则一直在不断发展,这些规则体现了不同操作系统设计哲学的差异。作为开发者,了解这些差异和背后的历史渊源非常有价值,本文将详细探讨Windows、macOS和Linux三大主流操作系统在文件名字符限制方面的差异和背后的历史原因。Wi......
  • Qt(二)弹窗类 颜色对话框 字体对话框 资源文件
    文章目录一、QDebug类和QMessagebox类(一)QDebug类:打印调试类(二)QMessagebox类:弹窗类2.修改组件图标(1)通过ui界面(2)通过QIcon的方式(3)通过QPixmap类3.使用示例(1)实例化对象实现2.静态函数版本二、颜色对话框和字体对话框类(一)QColorDialog(二)QFontDialog三、资源文件(一)添......
  • SQL Server 中用于备份数据库的 BACKUP 命令提供了多种选项和灵活性,主要包括以下几种:S
    SQLServer中用于备份数据库的BACKUP命令提供了多种选项和灵活性,主要包括以下几种:1.完整备份(FULL)完整备份将整个数据库备份到指定的备份介质(如磁盘或磁带)。语法如下:sqlCopyCodeBACKUPDATABASEdatabase_nameTOdisk='backup_device_path'[,...n]database_name:要备......
  • 1.1 PowerQuery从工作薄文件中获取数据
    PowerQuery从工作薄文件中获取数据时会自动生成四个步骤,点击【转换数据】后自动生成。尽管全是自动生成,只需要鼠标操作即可,但若了解这其中发生了什么,才更有利于以后更加方便的去处理其他复杂场景下的需求。搞清楚这四步都做了什么可点击【高级编辑器】查看这四步查询......