100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 【Java 虚拟机原理】Class 字节码二进制文件分析 一 ( 字节码文件附加信息 |

【Java 虚拟机原理】Class 字节码二进制文件分析 一 ( 字节码文件附加信息 |

时间:2021-04-14 12:03:46

相关推荐

【Java 虚拟机原理】Class 字节码二进制文件分析 一 ( 字节码文件附加信息 |

文章目录

一、字节码文件 与 JVM二、字节码文件示例三、字节码文件二进制结构分析1、魔数2、次版本号3、主版本号4、常量池个数

一、字节码文件 与 JVM

Java 源码编译成 Class 字节码 ;

Java 虚拟机 可以被认为是一个 解释器 , 解释编译后的 Class 字节码文件 , 最后在不同的操作系统中运行 ;

Android 虚拟机 不是 Java 规范的 虚拟机 , 有一些根据嵌入式设备进行的定制的实现 ;

Class 字节码 本质上就是 二进制数据 , 运行时 , 会被 类加载器 加载到 Java 虚拟机内存的 方法区 中 ; 同时 创建 Class 对象 ;

(Java 虚拟机内存分为 :堆区 , 方法区 , 栈 , 本地方法栈 , 程序计数器 )

由于要将 Class 字节码文件 加载到 JVM 内存的 方法区 中 , 要占用一定的内存空间 , 这里要求 Class 字节码文件 , 越小越好 ;

二、字节码文件示例

Java 源代码如下 :

public class Student {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}}

使用 javac 命令将 Student.java 源码编译成 Student.class字节码文件 :

javac Student.java

字节码文件二进制数据分析 :

使用二进制查看工具查看 Student.class 字节码文件 , 这些二进制数值对应的就是 JVM 指令 ;

CA FE BA BE 00 00 00 34 00 15 0A 00 04 00 11 09 00 03 00 12 07 00 13 07 00 14 01 00 04 6E 61 6D 65 01 00 12 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 00 07 67 65 74 4E 61 6D 65 01 00 14 28 29 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 07 73 65 74 4E 61 6D 65 01 00 15 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00 0C 53 74 75 64 65 6E 74 2E 6A 61 76 61 0C 00 07 00 08 0C 00 05 00 06 01 00 07 53 74 75 64 65 6E 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 00 21 00 03 00 04 00 00 00 01 00 02 00 05 00 06 00 00 00 03 00 01 00 07 00 08 00 01 00 09 00 00 00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 01 00 0A 00 00 00 06 00 01 00 00 00 01 00 01 00 0B 00 0C 00 01 00 09 00 00 00 1D 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 01 00 0A 00 00 00 06 00 01 00 00 00 05 00 01 00 0D 00 0E 00 01 00 09 00 00 00 22 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1 00 00 00 01 00 0A 00 00 00 0A 00 02 00 00 00 09 00 05 00 0A 00 01 00 0F 00 00 00 02 00 10

使用

javap -v Student.class

命令 , 生成上述字节码文件的 附加信息 ;

命令行输出 :

D:\jvm>javap -v Student.classClassfile /D:/jvm/Student.classLast modified -9-4; size 392 bytesMD5 checksum 8b9bb897bb8cf2a8addf04be5b7b915fCompiled from "Student.java"public class Studentminor version: 0major version: 52flags: ACC_PUBLIC, ACC_SUPERConstant pool:#1 = Methodref#4.#17 // java/lang/Object."<init>":()V#2 = Fieldref #3.#18 // Student.name:Ljava/lang/String;#3 = Class #19 // Student#4 = Class #20 // java/lang/Object#5 = Utf8name#6 = Utf8Ljava/lang/String;#7 = Utf8<init>#8 = Utf8()V#9 = Utf8Code#10 = Utf8LineNumberTable#11 = Utf8getName#12 = Utf8()Ljava/lang/String;#13 = Utf8setName#14 = Utf8(Ljava/lang/String;)V#15 = Utf8SourceFile#16 = Utf8Student.java#17 = NameAndType #7:#8// "<init>":()V#18 = NameAndType #5:#6// name:Ljava/lang/String;#19 = Utf8Student#20 = Utf8java/lang/Object{public Student();descriptor: ()Vflags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #1 // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 1: 0public java.lang.String getName();descriptor: ()Ljava/lang/String;flags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: getfield#2 // Field name:Ljava/lang/String;4: areturnLineNumberTable:line 5: 0public void setName(java.lang.String);descriptor: (Ljava/lang/String;)Vflags: ACC_PUBLICCode:stack=2, locals=2, args_size=20: aload_01: aload_12: putfield#2 // Field name:Ljava/lang/String;5: returnLineNumberTable:line 9: 0line 10: 5}SourceFile: "Student.java"

下面开始逐个字节解析上述字节码文件 ;

三、字节码文件二进制结构分析

分析字节码二进制文件时 , 可以参考javap -v Student.class命令输出的字节码附加信息进行理解 ;

1、魔数

magic ( 魔数 ) :444 字节 ,CA FE BA BE, 所有的 Class 字节码都是以 CafeBabe 信息开头的 ;

2、次版本号

minor_version ( 次版本号 ) :222 字节 ,00 00, 次版本号是 000 ; 对应字节码附加信息中的minor version: 0;

3、主版本号

major_version ( 主版本号 ) :222 字节 ,00 34, 主版本号是 525252 ; 对应字节码附加信息中的major version: 52;

这个主版本号 525252 对应 JDK 版本的 1.81.81.8 版本 ;515151 对应 1.71.71.7 ;535353 对应 1.91.91.9 ;454545 对应 1.01.01.0 ;

4、常量池个数

constant_pool_count ( 常量池个数 ) :222 字节 ,00 15, 常量池个数是 212121 个 ; 由于 JVM 占用了默认的常量池 #0 , 因此实际上的常量个数是 21−121 - 121−1 个 , 需要对这个数减一处理 ;

字节码附加信息中 常量池参考 , 有 20 个常量池 ; #0 常量池 , 被 JVM 占用了 , 代表了一个空引用 , 不指向任何位置 ;

Constant pool:#1 = Methodref#4.#17 // java/lang/Object."<init>":()V#2 = Fieldref #3.#18 // Student.name:Ljava/lang/String;#3 = Class #19 // Student#4 = Class #20 // java/lang/Object#5 = Utf8name#6 = Utf8Ljava/lang/String;#7 = Utf8<init>#8 = Utf8()V#9 = Utf8Code#10 = Utf8LineNumberTable#11 = Utf8getName#12 = Utf8()Ljava/lang/String;#13 = Utf8setName#14 = Utf8(Ljava/lang/String;)V#15 = Utf8SourceFile#16 = Utf8Student.java#17 = NameAndType #7:#8// "<init>":()V#18 = NameAndType #5:#6// name:Ljava/lang/String;#19 = Utf8Student#20 = Utf8java/lang/Object

【Java 虚拟机原理】Class 字节码二进制文件分析 一 ( 字节码文件附加信息 | 魔数 | 次版本号 | 主版本号 | 常量池个数 )

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。