深入浅出JVM(1)

本文基于jdk1.8和官方文档进行阐述,有兴趣的可以到官网上看看https://docs.oracle.com/javase/8/

JDK、JRE、JVM的关系

JDK 8是JRE 8的超集,包含JRE 8中的所有内容,以及开发小程序和应用程序所需的工具,例如编译器和调试器。JRE 8提供了库,Java虚拟机(JVM)和其他组件,以运行用Java编程语言编写的小程序和应用程序。请注意,JRE包含Java SE规范不需要的组件,包括标准和非标准Java组件。
在这里插入图片描述
熟悉Java的人都知道,Java源文件(源码)经过编译,生成".class"(类文件)字节码文件,再由jvn加载“.class”文件并运行。接下来来看看源码是如何编译成类文件的

源码到类文件

源码demo

class Person{
	private String name="carl";
    private int age;
	private final double salary=100;
    private static String address;
    private final static String hobby="Programming";
	private static Object obj=new Object();
    public void say(){
        System.out.println("person say...");
    }
    public static int calc(int op1,int op2){
        op1=3;
        int result=op1+op2;
		Object obj=new Object();
        return result;
    }
	public static void main(String[] args){
		calc(1,2);
	}
}

前期的编译:Person.java–>词法分析器–>tokens流–>语法分析器–>语法树/抽象语法树–>语义分析器–>注解抽象语法树–>字节码生成器–>Person.class
经过编译后生成的类文件是一个16进制文件,如:

cafe babe 0000 0034 003f 0a00 0a00 2b08
002c 0900 0d00 2d06 4059 0000 0000 0000
0900 0d00 2e09 002f 0030 0800 310a 0032
0033 0700 340a 000d 0035 0900 0d00 3607
0037 0100 046e 616d 6501 0012 4c6a 6176
612f 6c61 6e67 2f53 7472 696e 673b 0100
0361 6765 0100 0149 0100 0673 616c 6172
7901 0001 4401 000d 436f 6e73 7461 6e74
......

关于类文件中的结构(进制所表示的含义)官网也给了我们一个参考:

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];
}

其中u2、u4表示两个字节、4个字节
magic:The magic item supplies the magic number identifying the class file format(该magic项目提供标识class文件格式的魔数,个人理解:标识此类是Java类还是非Java类)

minor_version,major_version
minor_version 和major_version项目 的值是此class文件的次要和主要版本号。主版本号和次版本号共同确定class文件格式的版本 。如果class文件的主要版本号为M,次要版本号为m,则将其class文件格式的版本表示为Mm。因此,class文件格式版本可以按字典顺序排序,例如1.5 <2.0 <2.1。

constant_pool_count(u2:003f=63,10进制)
该constant_pool_count项目的值等于表中的条目数constant_pool加一。

cp_info constant_pool[constant_pool_count-1]
cp_info表示的是常量池,constant_pool表示常量池的数量,constant_pool_count-1为具体数值,表示常量池中的数量是62。
constant_pool是结构的表(代表各种串常量,类和接口名,字段名,和本内提到的其他常量)ClassFile 结构和其子结构。每个constant_pool表条目的格式 由其第一个“标签”字节指示。该constant_pool表的索引从1到constant_pool_count-1

常量池主要存储两方面的内容:字面量和符号引用
字面量:文本字符串,final修饰等
符号引用:类和接口的全限定名、字段名称和描述符、方法名称和描述符

cp_info其实就是一个表格的形式
All constant_pool table entries have the following general format:(所有constant_pool表条目均具有以下常规格式:)

cp_info {
 u1 tag;//标签
 u1 info[];
}

在这里插入图片描述
往下数一个u1,即0a->10:代表的是CONSTANT_Methodref,表示这是一个方法引用

 CONSTANT_Fieldref_info {
  	u1 tag;
  	u2 class_index;
  	u2 name_and_type_index;
 }

往下数u2和u2
u2,即00 0a->10:代表的是class_index,表示该方法所属的类在常量池中的索引 u2,即00 2b->43:代表的是name_and_type_index,表示该方法的名称和类型的索引

#1 = Methodref       #10,#43

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

CONSTANT_String_info {
  u1 tag;
  u2 string_index;
 }

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

#1 = Methodref       #10,#43
#2 = String          #44

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

 CONSTANT_Fieldref_info {
  u1 tag;
  u2 class_index;
  u2 name_and_type_index;
 }

往下数u2和u2
u2,即00 0d->13:代表的是class_index
u2,即00 2d->45:代表的是name_and_type_index

#1 = Methodref       #10.#43
#2 = String          #44
#3 = Fieldref        #13.#45 

其他类文件结构的含义有兴趣可以到官网上看看,这里就不在阐述!

javap验证
JDK自带的命令:Javap -h
可以验证一下上述Classfile Structure前面几块内容的正确性。
javap -v -p Person.class 进行反编译,查看字节码信息和指令等信息。

JVM相对class文件来说可以理解为是操作系统;class文件相对JVM来说可以理解为是汇编语言或者机器语言。
在这里插入图片描述

本文到此结束!本文到此结束!有什么不足的地方请在评论区指明,谢谢!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值