02详解字节码文件

1.使用正确的软件打开字节码文件

字节码文件中保存了源代码编译之后的内容,以二进制的方式存储,无法直接用记事本打开阅读。
通过NotePad++使用十六进制插件查看class文件:

可以使用jclasslib来直观看到字节码问题。jclasslib下载地址:Releases · ingokegel/jclasslib

使用jclasslib打开字节码文件可以看到具体内容

2.字节码文件组成

字节码文件组成分为:

  • 基础信息:包括 魔数、字节码文件对应的java版本号、访问标识(public final等)、父类和接口等。
  • 常量池:包括了字符串常量、类或接口名、字段名,主要在字节码指令中使用。
  • 字段:当前类或接口声明的字段信息。
  • 方法:当前类或接口声明的方法信息、字节码指令。
  • 属性:类的属性,比如源码的文件名、内部类的列表等。

2.1基本信息

1.Magic魔数

Magic魔数就是文件开头会有一段标识信息,让虚拟机识别到这个文件是java的class文件,java的魔数是“cafebabe”。

其实不止有java的class文件有魔术,文件是无法通过文件扩展名来确定文件类型的,文件扩展名可以随意修改,不影响文件的内容。软件使用文件的头几个字节(文件头)去校验文件的类型,如果软件不支持该种类型就会出错。

2.主副版本号

主版本号用来标识大版本号,JDK1.0-1.1使用了45.0-45.3,JDK1.2是46之后每升级一个大版本就加1;副版本号是当主版本号相同时作为区分不同版本的标识,一般只需要关心主版本号。

版本号的作用主要是判断当前字节码的版本和运行时的JDK是否兼容。

这种情况有两种解决方法:
1.升级JDK版本(不推荐,因为有的依赖只有当前JDK版本才能使用,如果冒然升级JDK版本会导致其他依赖报错)
2.降低依赖的版本(推荐)

可以通过jclasslib看到字节码文件的组成信息

2.2常量池

中常量池的作用:避免相同的内容重复定义,节省空间。

常量池中的数据都有一个编号,编号从1开始。在字段或者字节码指令中通过编号可以快速的找到对应的数据。字节码指令中通过编号引用到常量池的过程称之为符号引用。

2.3方法

字节码中的方法区域是存放字节码指令的核心位置,字节码指令的内容存放在方法的Code属性中。

方法的内容主要放到操作数栈和局部变量表数组。

3.分析字符码常用工具

3.1 javap-v命令

javap-v是java自带的,适合在服务器上使用。

输入javap -v 字节码文件名称 查看具体的字节码信息。(如果jar包需要先使用 jar –xvf命令解压)

但是这个工具很简陋,正常本地调试可以使用arthas

3.2 arthas

Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,大大提升线上问题排查效率。

简介 | arthas

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注