jvm初识

1 官网

1.1 JDK 8

https://docs.oracle.com/javase/8/

1.2 The relation of JDK/JRE/JVM

Reference -> Developer Guides -> 定位到:https://docs.oracle.com/javase/8/docs/index.html

1.3 源码到类文件

1.3.1 源码

1
2
3
4
5
6
7
8
9
10
11
12
class Person{
private String name;
private int age;
private static String address;
private final static String hobby = "Programming";
public void say(){
System.out.printLn("person say .....");
}
public int calc(int op1, int op2){
return op1 + op2;
}
}

编译:javac Person.java -> Person.class

1.3.2 编译过程

Person.java -> 词法分析器 -> tokens流 -> 语法分析器 -> 语法树/抽象语法树 -> 语义分析器 -> 注解抽象语法树 -> 字节码生成器 -> Person.class文件

​ 由上可知:编译器其实做的事情就是“对等信息转换”。java文件中的信息其实跟class文件中的信息是一样的。

1.3.3 类文件(class文件)

官网: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html

  1. magic(魔数):The magic item supplies the magic number identifying the file format; it has the value 0xCAFEBABE:café babe.

  2. minor_version, major_version:0000 0034 对应十进制的52,代表JDK8中的一个版本

  3. constant_pool_count:003f 对应十进制63代表常量池中62个常量

常量池中主要存储两方面的内容:字面量和符号引用。

1
2
字面量:文本字符串,final修饰等
符号引用:类和接口的全限定名、字段名称和描述符、方法名称和描述符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ClassFile{
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}

.class字节码文件

1
2
3
4
5
6
7
魔术和class文件版本
常量池
访问标志
类索引、父类索引、接口索引
字段表集合
方法表集合
属性表集合

1.3.4 反编译验证

用javap指令验证上述猜想正确性。编译指令:javap -v -p Person.class

进行反编译之后,查看字节码信息和指令等信息。JVM相对class文件来说可以理解为是操作系统;class文件相对JVM来说可以理解是汇编语言或者机器语言。

上面分析到常量池中常量的数量是62,接下来来具体分析一下这62个常量,也就是这块包含的信息:cp_info constant_pool[constant_pool_count-1],cp其实就是一个表格的形式。

1
2
3
4
cp_info {
u1 tag;
u1 info[];
}

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4

(1)往下数一个u1,即0a->10:代表的是CONSTANT_Methodref,表示这是一个方法引用

1
2
3
4
5
CONSTANT_Fieldref_info{
u1 tag;
u2 class_index;
u2 name_and_type_index;
}

往下数两个u2:

​ 第一个u2,即00 0a->10:代表的是class_index,表示该方法所属的类在常量池中的索引

​ 第二个u2,即00 2b->43:代表的是name_and_type_index,表示该方法的名称和类型的索引。

(2)往下数u1,即08->8:表示的是CONSTANT_String,表示字符串类型

1
2
3
4
CONSTANT_String_info {
u1 tag;
u2 string_index;
}

往下数u2,即00 2c->44:代表的是string_index

(3)往下数u1,即09 ->9:表示CONSTANT_Fieldref,表示字段类型

1
2
3
4
5
CONSTANT_Fieldref_info{
u1 tag;
u2 class_index;
u2 name_and_type_index;
}

往下数两个u2:

​ 第一个u2:即00 0d ->13:代表的是class_index

​ 第二个u2:即00 2d ->45:代表的是name_and_type_index


jvm初识
http://www.zivjie.cn/2023/03/11/java基础/jvm/jvm初识/
作者
Francis
发布于
2023年3月11日
许可协议