JVM字节码文件浅谈

文章目录

  • 版权声明
  • java虚拟机的组成
  • 字节码文件
    • 打开字节码文件的姿势
    • 字节码文件的组成
      • 魔数(基本信息)
      • 主副版本号(基本信息)
      • 主版本号不兼容的错误解决方法
      • 基本信息
      • 常量池
      • 方法
    • 字节码文件的常用工具
      • javap -v命令
      • jclasslib插件
      • 阿里arthas

版权声明

  • 本博客的内容基于我个人学习黑马程序员课程的学习笔记整理而成。我特此声明,所有版权属于黑马程序员或相关权利人所有。本博客的目的仅为个人学习和交流之用,并非商业用途。
  • 我在整理学习笔记的过程中尽力确保准确性,但无法保证内容的完整性和时效性。本博客的内容可能会随着时间的推移而过时或需要更新。
  • 若您是黑马程序员或相关权利人,如有任何侵犯版权的地方,请您及时联系我,我将立即予以删除或进行必要的修改。
  • 对于其他读者,请在阅读本博客内容时保持遵守相关法律法规和道德准则,谨慎参考,并自行承担因此产生的风险和责任。本博客中的部分观点和意见仅代表我个人,不代表黑马程序员的立场。

java虚拟机的组成

JVM包含以下组成部分:

  1. 类加载器(Class Loader):负责将Java字节码加载到JVM中,并将其转换为JVM可以理解的格式。

  2. 运行时数据区(Runtime Data Area):JVM在运行时会将内存划分为不同的数据区域,包括方法区、堆、栈、程序计数器等,用于存储程序运行时所需要的数据。

  3. 执行引擎(Execution Engine):负责执行Java字节码,将其转换为机器码并执行。

  4. 本地方法接口(Native Interface):提供了与本地代码交互的接口,可以使用C、C++等语言编写本地代码,并通过JNI(Java Native Interface)与Java程序交互。

  5. Java标准库(Java API):提供了大量的类和接口,包括I/O、网络、集合、线程等常用功能。

JVM字节码文件浅谈_第1张图片
JVM字节码文件浅谈_第2张图片

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

字节码文件

打开字节码文件的姿势

  1. 使用Jclasslib工具,idea中可以直接安装jclasslib插件
    JVM字节码文件浅谈_第3张图片
  2. 然后打开字节码文件后,选择工具栏中的视图->shoe ByteCode with jclasslib,即可
    JVM字节码文件浅谈_第4张图片

JVM字节码文件浅谈_第5张图片

  • 如果源码文件修改后,字节码文件为未更新,选择构建重新编译文件即可!
    JVM字节码文件浅谈_第6张图片

字节码文件的组成

  • Java字节码文件是一种中间代码,它包含了Java程序的编译版本。
  • 字节码文件的组成结构主要包括以下几个部分:
    JVM字节码文件浅谈_第7张图片
Magic Number
Version
Constant Pool
Access Flags
Class Index
Parent Class Index
Interface Indexes
接口
Field Table
Method Table
字段信息
方法信息
Attribute Table

魔数(基本信息)

  1. 魔数(Magic Number):Java字节码文件的开头四个字节是一个魔数,它是一个特殊的标识,用于表明这是一个有效的字节码文件。
    JVM字节码文件浅谈_第8张图片
    • 文件是无法通过文件扩展名来确定文件类型的,文件扩展名可以随意修改,不影响文件的内容。
    • 软件使用文件的头几个字节(文件头)去校验文件的类型,如果软件不支持该种类型就会出错
    • 魔数的数值为0xCAFEBABE
      JVM字节码文件浅谈_第9张图片

主副版本号(基本信息)

  1. 版本信息:紧随魔数后的两个字节表示Java字节码文件的主版本号和次版本号
    • 主副版本号指的是编译字节码文件的JDK版本号,主版本号用来标识大版本号,JDK1.0-1.1使用了45.0-45.3,JDK1.2是46之后每升级一个大版本就加1
    • 副版本号是当主版本号相同时作为区分不同版本的标识,一般只需要关心主版本号。
    • 版本号的作用主要是判断当前字节码的版本和运行时的JDK是否兼容

JVM字节码文件浅谈_第10张图片


主版本号不兼容的错误解决方法

  • 解决以下由于主版本号不兼容导致的错误
    在这里插入图片描述
    两种方案:
  1. 升级JDK版本(容易引发其他的兼容性问题,并且需要大量的测试)
  2. 建议采用:将第三方依赖的版本号降低或者更换依赖,以满足JDK版本的要求

基本信息

  • 上面的魔数和主副版本号都属于基本信息部分,基本信息还包含
    • 访问标志(Access Flags):这个字段定义了类或接口的访问权限,例如public、final、abstract等。
    • 类和父类信息:字节码文件包括了对当前类的名称和父类的名称的引用。这些引用通常以全限定名的形式出现,例如java/lang/Object。
    • 接口表(Interfaces):这个表格包含了类实现的接口的索引,用于描述类的继承关系。
      JVM字节码文件浅谈_第11张图片

常量池

  • 常量池(Constant Pool):它是一个表格结构,用于存储字面值、符号引用、字段和方法的描述等各种常量。
    • 字节码文件中常量池的作用:避免相同的内容重复定义,节省空间
    • 常量池在字节码文件中起到类似符号表的作用,它包含了类文件中用到的各种符号和字面值。
    • 常量池中的常量索引从1开始,0被用于表示不引用任何常量。
    • 字节码指令中通过编号引用到常量池的过程称之为符号引用
      JVM字节码文件浅谈_第12张图片
  1. 字段表(Fields):这个表格包含了类的字段的描述,包括字段名、字段类型以及访问标志。
  2. 属性表(Attributes):每个类、字段和方法可以包含属性表,用于存储额外的信息。属性表通常包括源代码行号、局部变量表信息、异常处理信息等。
  3. 字节码指令集:字节码文件包含了实际的字节码指令,这些指令定义方法的具体操作和行为。字节码指令集是由一系列操作码(opcode)和操作数组成,用于执行方法中的逻辑。

方法

  • 字节码中的方法区域是存放字节码指令的核心位置,字节码指令的内容存放在方法的Code属性中
    JVM字节码文件浅谈_第13张图片
  • 操作数栈是临时存放数据的地方,局部变量表是存放方法中的局部变量的位置
    JVM字节码文件浅谈_第14张图片
  • i=i++的执行流程
    JVM字节码文件浅谈_第15张图片
  • i=++i的执行流程
    JVM字节码文件浅谈_第16张图片
  • 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插件

  1. 使用Jclasslib工具,idea中可以直接安装jclasslib插件
    JVM字节码文件浅谈_第17张图片
  2. 然后打开字节码文件后,选择工具栏中的视图->shoe ByteCode with jclasslib,即可
    JVM字节码文件浅谈_第18张图片

JVM字节码文件浅谈_第19张图片

  • 如果源码文件修改后,字节码文件为未更新,选择构建重新编译文件即可!
    JVM字节码文件浅谈_第20张图片

阿里arthas

JVM字节码文件浅谈_第21张图片

  • Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,大大提升线上问题排查效率。
  • 官网
    JVM字节码文件浅谈_第22张图片
  • 具体使用,可以去B站或官网学习使用!

你可能感兴趣的:(jvm)