文章目录
- 版权声明
- java虚拟机的组成
- 字节码文件
-
- 打开字节码文件的姿势
- 字节码文件的组成
- 字节码文件的常用工具
-
- [javap -v命令](#javap -v命令)
- jclasslib插件
- 阿里arthas
版权声明
- 本博客的内容基于我个人学习黑马程序员课程的学习笔记整理而成。我特此声明,所有版权属于黑马程序员或相关权利人所有。本博客的目的仅为个人学习和交流之用,并非商业用途。
- 我在整理学习笔记的过程中尽力确保准确性,但无法保证内容的完整性和时效性。本博客的内容可能会随着时间的推移而过时或需要更新。
- 若您是黑马程序员或相关权利人,如有任何侵犯版权的地方,请您及时联系我,我将立即予以删除或进行必要的修改。
- 对于其他读者,请在阅读本博客内容时保持遵守相关法律法规和道德准则,谨慎参考,并自行承担因此产生的风险和责任。本博客中的部分观点和意见仅代表我个人,不代表黑马程序员的立场。
java虚拟机的组成
JVM包含以下组成部分:
-
类加载器(Class Loader):负责将Java字节码加载到JVM中,并将其转换为JVM可以理解的格式。
-
运行时数据区(Runtime Data Area):JVM在运行时会将内存划分为不同的数据区域,包括方法区、堆、栈、程序计数器等,用于存储程序运行时所需要的数据。
-
执行引擎(Execution Engine):负责执行Java字节码,将其转换为机器码并执行。
-
本地方法接口(Native Interface):提供了与本地代码交互的接口,可以使用C、C++等语言编写本地代码,并通过JNI(Java Native Interface)与Java程序交互。
-
Java标准库(Java API):提供了大量的类和接口,包括I/O、网络、集合、线程等常用功能。
Java Virtual Machine Runtime Data Area Loads Loads Used by Used by Used by Controls Calls Interacts with Optional: JIT Compiler Class Loader Execution Engine Native Interface Java Standard Library Method Area Heap Stacks Program Counter Register Native Method Stack
字节码文件
打开字节码文件的姿势
- 使用Jclasslib工具,idea中可以直接安装jclasslib插件
- 然后打开字节码文件后,选择工具栏中的视图->shoe ByteCode with jclasslib,即可
- 如果源码文件修改后,字节码文件为未更新,选择构建重新编译文件即可!
字节码文件的组成
- Java字节码文件是一种中间代码,它包含了Java程序的编译版本。
- 字节码文件的组成结构主要包括以下几个部分:
Magic Number Version Constant Pool Access Flags Class Index Parent Class Index Interface Indexes 类 接口 Field Table Method Table 字段信息 方法信息 Attribute Table
魔数(基本信息)
- 魔数(Magic Number):Java字节码文件的开头四个字节是一个魔数 ,它是一个特殊的标识 ,用于表明这是一个有效的字节码文件。
- 文件是无法通过文件扩展名来确定文件类型的,文件扩展名可以随意修改,不影响文件的内容。
- 软件使用文件的头几个字节(文件头)去校验文件的类型,如果软件不支持该种类型就会出错
- 魔数的数值为
0xCAFEBABE
。
主副版本号(基本信息)
- 版本信息:紧随魔数后的两个字节表示Java字节码文件的主版本号和次版本号 。
- 主副版本号指的是编译字节码文件的JDK版本号,主版本号用来标识大版本号,JDK1.0-1.1使用了45.0-45.3,JDK1.2是46之后每升级一个大版本就加1
- 副版本号是当主版本号相同时作为区分不同版本的标识,一般只需要关心主版本号。
- 版本号的作用主要是判断当前字节码的版本和运行时的JDK是否兼容
主版本号不兼容的错误解决方法
- 解决以下由于主版本号不兼容导致的错误
两种方案:
- 升级JDK版本(容易引发其他的兼容性问题,并且需要大量的测试)
- 建议采用:将第三方依赖的版本号降低或者更换依赖,以满足JDK版本的要求
基本信息
- 上面的魔数和主副版本号都属于基本信息部分,基本信息还包含
- 访问标志(Access Flags):这个字段定义了类或接口的访问权限,例如public、final、abstract等。
- 类和父类信息:字节码文件包括了对当前类的名称和父类的名称的引用。这些引用通常以全限定名的形式出现,例如java/lang/Object。
- 接口表(Interfaces):这个表格包含了类实现的接口的索引,用于描述类的继承关系。
常量池
- 常量池(Constant Pool):它是一个表格结构,用于存储字面值、符号引用、字段和方法的描述等各种常量。
- 字节码文件中常量池的作用:避免相同的内容重复定义,节省空间
- 常量池在字节码文件中起到类似符号表的作用,它包含了类文件中用到的各种符号和字面值。
- 常量池中的常量索引从1开始,0被用于表示不引用任何常量。
- 字节码指令中通过编号引用到常量池的过程称之为符号引用
- 字段表(Fields):这个表格包含了类的字段的描述,包括字段名、字段类型以及访问标志。
- 属性表(Attributes):每个类、字段和方法可以包含属性表,用于存储额外的信息。属性表通常包括源代码行号、局部变量表信息、异常处理信息等。
- 字节码指令集:字节码文件包含了实际的字节码指令,这些指令定义方法的具体操作和行为。字节码指令集是由一系列操作码(opcode)和操作数组成,用于执行方法中的逻辑。
方法
- 字节码中的方法区域是存放字节码指令的核心位置,字节码指令的内容存放在方法的Code属性中
- 操作数栈是临时存放数据的地方,局部变量表是存放方法中的局部变量的位置
- i=i++的执行流程
- i=++i的执行流程
- int i = 0; i = i++; 最终i的值是多少?
- 答案是0,通过分析字节码指令发现,i++先把0取出来放入临时的操作数栈中,接下来对i进行加1,i变成了1,最后再将之前保存的临时值0放入i,最后i就变成了0。
字节码文件的常用工具
javap -v命令
- javap是JDK自带的反编译工具,可以通过控制台查看字节码文件的内容。适合在服务器上查看字节码文件内容。
- 直接输入javap查看所有参数
- 输入javap -v 字节码文件名称 查看具体的字节码信息。(如果jar包需要先使用 jar --xvf 命令解压)
jclasslib插件
- 使用Jclasslib工具,idea中可以直接安装jclasslib插件
- 然后打开字节码文件后,选择工具栏中的视图->shoe ByteCode with jclasslib,即可
- 如果源码文件修改后,字节码文件为未更新,选择构建重新编译文件即可!
阿里arthas
- Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,大大提升线上问题排查效率。
- 官网
- 具体使用,可以去B站或官网学习使用!